Skip to content

Commit 1f07b03

Browse files
authored
feat: add weekly contest 429 (#3877)
1 parent 7c9283e commit 1f07b03

File tree

18 files changed

+1080
-1
lines changed

18 files changed

+1080
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
---
2+
comments: true
3+
difficulty: 简单
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3396.Minimum%20Number%20of%20Operations%20to%20Make%20Elements%20in%20Array%20Distinct/README.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3396. 使数组元素互不相同所需的最少操作次数](https://leetcode.cn/problems/minimum-number-of-operations-to-make-elements-in-array-distinct)
10+
11+
[English Version](/solution/3300-3399/3396.Minimum%20Number%20of%20Operations%20to%20Make%20Elements%20in%20Array%20Distinct/README_EN.md)
12+
13+
## 题目描述
14+
15+
<!-- description:start -->
16+
17+
<p>给你一个整数数组 <code>nums</code>,你需要确保数组中的元素&nbsp;<strong>互不相同&nbsp;</strong>。为此,你可以执行以下操作任意次:</p>
18+
19+
<ul>
20+
<li>从数组的开头移除 3 个元素。如果数组中元素少于 3 个,则移除所有剩余元素。</li>
21+
</ul>
22+
23+
<p><strong>注意:</strong>空数组也视作为数组元素互不相同。返回使数组元素互不相同所需的&nbsp;<strong>最少操作次数&nbsp;</strong>。<!-- notionvc: 210ee4f2-90af-4cdf-8dbc-96d1fa8f67c7 --></p>
24+
25+
<p>&nbsp;</p>
26+
27+
<p>&nbsp;</p>
28+
29+
<p><strong class="example">示例 1:</strong></p>
30+
31+
<div class="example-block">
32+
<p><strong>输入:</strong> <span class="example-io">nums = [1,2,3,4,2,3,3,5,7]</span></p>
33+
34+
<p><strong>输出:</strong> <span class="example-io">2</span></p>
35+
36+
<p><strong>解释:</strong></p>
37+
38+
<ul>
39+
<li>第一次操作:移除前 3 个元素,数组变为 <code>[4, 2, 3, 3, 5, 7]</code>。</li>
40+
<li>第二次操作:再次移除前 3 个元素,数组变为 <code>[3, 5, 7]</code>,此时数组中的元素互不相同。</li>
41+
</ul>
42+
43+
<p>因此,答案是 2。</p>
44+
</div>
45+
46+
<p><strong class="example">示例 2:</strong></p>
47+
48+
<div class="example-block">
49+
<p><strong>输入:</strong> <span class="example-io">nums = [4,5,6,4,4]</span></p>
50+
51+
<p><strong>输出:</strong> <span class="example-io">2</span></p>
52+
53+
<p><strong>解释:</strong></p>
54+
55+
<ul>
56+
<li>第一次操作:移除前 3 个元素,数组变为 <code>[4, 4]</code>。</li>
57+
<li>第二次操作:移除所有剩余元素,数组变为空。</li>
58+
</ul>
59+
60+
<p>因此,答案是 2。</p>
61+
</div>
62+
63+
<p><strong class="example">示例 3:</strong></p>
64+
65+
<div class="example-block">
66+
<p><strong>输入:</strong> <span class="example-io">nums = [6,7,8,9]</span></p>
67+
68+
<p><strong>输出:</strong> <span class="example-io">0</span></p>
69+
70+
<p><strong>解释:</strong></p>
71+
72+
<p>数组中的元素已经互不相同,因此不需要进行任何操作,答案是 0。</p>
73+
</div>
74+
75+
<p>&nbsp;</p>
76+
77+
<p><strong>提示:</strong></p>
78+
79+
<ul>
80+
<li><code>1 &lt;= nums.length &lt;= 100</code></li>
81+
<li><code>1 &lt;= nums[i] &lt;= 100</code></li>
82+
</ul>
83+
84+
<!-- description:end -->
85+
86+
## 解法
87+
88+
<!-- solution:start -->
89+
90+
### 方法一:哈希表 + 倒序遍历
91+
92+
我们可以倒序遍历数组 $\textit{nums}$,并使用哈希表 $\textit{s}$ 记录已经遍历过的元素。当遍历到元素 $\textit{nums}[i]$ 时,如果 $\textit{nums}[i]$ 已经在哈希表 $\textit{s}$ 中,那么说明我们需要移除 $\textit{nums}[0..i]$ 的所有元素,需要的操作次数为 $\left\lfloor \frac{i}{3} \right\rfloor + 1$。否则,我们将 $\textit{nums}[i]$ 加入哈希表 $\textit{s}$ 中,并继续遍历下一个元素。
93+
94+
遍历结束后,如果没有找到重复的元素,那么数组中的元素已经互不相同,不需要进行任何操作,答案为 $0$。
95+
96+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。
97+
98+
<!-- tabs:start -->
99+
100+
#### Python3
101+
102+
```python
103+
class Solution:
104+
def minimumOperations(self, nums: List[int]) -> int:
105+
s = set()
106+
for i in range(len(nums) - 1, -1, -1):
107+
if nums[i] in s:
108+
return i // 3 + 1
109+
s.add(nums[i])
110+
return 0
111+
```
112+
113+
#### Java
114+
115+
```java
116+
class Solution {
117+
public int minimumOperations(int[] nums) {
118+
Set<Integer> s = new HashSet<>();
119+
for (int i = nums.length - 1; i >= 0; --i) {
120+
if (s.contains(nums[i])) {
121+
return i / 3 + 1;
122+
}
123+
s.add(nums[i]);
124+
}
125+
return 0;
126+
}
127+
}
128+
```
129+
130+
#### C++
131+
132+
```cpp
133+
class Solution {
134+
public:
135+
int minimumOperations(vector<int>& nums) {
136+
unordered_set<int> s;
137+
for (int i = nums.size() - 1; ~i; --i) {
138+
if (s.contains(nums[i])) {
139+
return i / 3 + 1;
140+
}
141+
s.insert(nums[i]);
142+
}
143+
return 0;
144+
}
145+
};
146+
```
147+
148+
#### Go
149+
150+
```go
151+
func minimumOperations(nums []int) int {
152+
s := map[int]bool{}
153+
for i := len(nums) - 1; i >= 0; i-- {
154+
if s[nums[i]] {
155+
return i/3 + 1
156+
}
157+
s[nums[i]] = true
158+
}
159+
return 0
160+
}
161+
```
162+
163+
#### TypeScript
164+
165+
```ts
166+
function minimumOperations(nums: number[]): number {
167+
const s = new Set<number>();
168+
for (let i = nums.length - 1; ~i; --i) {
169+
if (s.has(nums[i])) {
170+
return Math.ceil((i + 1) / 3);
171+
}
172+
s.add(nums[i]);
173+
}
174+
return 0;
175+
}
176+
```
177+
178+
<!-- tabs:end -->
179+
180+
<!-- solution:end -->
181+
182+
<!-- problem:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
---
2+
comments: true
3+
difficulty: Easy
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3396.Minimum%20Number%20of%20Operations%20to%20Make%20Elements%20in%20Array%20Distinct/README_EN.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3396. Minimum Number of Operations to Make Elements in Array Distinct](https://leetcode.com/problems/minimum-number-of-operations-to-make-elements-in-array-distinct)
10+
11+
[中文文档](/solution/3300-3399/3396.Minimum%20Number%20of%20Operations%20to%20Make%20Elements%20in%20Array%20Distinct/README.md)
12+
13+
## Description
14+
15+
<!-- description:start -->
16+
17+
<p>You are given an integer array <code>nums</code>. You need to ensure that the elements in the array are <strong>distinct</strong>. To achieve this, you can perform the following operation any number of times:</p>
18+
19+
<ul>
20+
<li>Remove 3 elements from the beginning of the array. If the array has fewer than 3 elements, remove all remaining elements.</li>
21+
</ul>
22+
23+
<p><strong>Note</strong> that an empty array is considered to have distinct elements. Return the <strong>minimum</strong> number of operations needed to make the elements in the array distinct.<!-- notionvc: 210ee4f2-90af-4cdf-8dbc-96d1fa8f67c7 --></p>
24+
25+
<p>&nbsp;</p>
26+
<p><strong class="example">Example 1:</strong></p>
27+
28+
<div class="example-block">
29+
<p><strong>Input:</strong> <span class="example-io">nums = [1,2,3,4,2,3,3,5,7]</span></p>
30+
31+
<p><strong>Output:</strong> <span class="example-io">2</span></p>
32+
33+
<p><strong>Explanation:</strong></p>
34+
35+
<ul>
36+
<li>In the first operation, the first 3 elements are removed, resulting in the array <code>[4, 2, 3, 3, 5, 7]</code>.</li>
37+
<li>In the second operation, the next 3 elements are removed, resulting in the array <code>[3, 5, 7]</code>, which has distinct elements.</li>
38+
</ul>
39+
40+
<p>Therefore, the answer is 2.</p>
41+
</div>
42+
43+
<p><strong class="example">Example 2:</strong></p>
44+
45+
<div class="example-block">
46+
<p><strong>Input:</strong> <span class="example-io">nums = [4,5,6,4,4]</span></p>
47+
48+
<p><strong>Output:</strong> 2</p>
49+
50+
<p><strong>Explanation:</strong></p>
51+
52+
<ul>
53+
<li>In the first operation, the first 3 elements are removed, resulting in the array <code>[4, 4]</code>.</li>
54+
<li>In the second operation, all remaining elements are removed, resulting in an empty array.</li>
55+
</ul>
56+
57+
<p>Therefore, the answer is 2.</p>
58+
</div>
59+
60+
<p><strong class="example">Example 3:</strong></p>
61+
62+
<div class="example-block">
63+
<p><strong>Input:</strong> <span class="example-io">nums = [6,7,8,9]</span></p>
64+
65+
<p><strong>Output:</strong> <span class="example-io">0</span></p>
66+
67+
<p><strong>Explanation:</strong></p>
68+
69+
<p>The array already contains distinct elements. Therefore, the answer is 0.</p>
70+
</div>
71+
72+
<p>&nbsp;</p>
73+
<p><strong>Constraints:</strong></p>
74+
75+
<ul>
76+
<li><code>1 &lt;= nums.length &lt;= 100</code></li>
77+
<li><code>1 &lt;= nums[i] &lt;= 100</code></li>
78+
</ul>
79+
80+
<!-- description:end -->
81+
82+
## Solutions
83+
84+
<!-- solution:start -->
85+
86+
### Solution 1: Hash Table + Reverse Traversal
87+
88+
We can traverse the array $\textit{nums}$ in reverse order and use a hash table $\textit{s}$ to record the elements that have already been traversed. When we encounter an element $\textit{nums}[i]$, if $\textit{nums}[i]$ is already in the hash table $\textit{s}$, it means we need to remove all elements from $\textit{nums}[0..i]$. The number of operations required is $\left\lfloor \frac{i}{3} \right\rfloor + 1$. Otherwise, we add $\textit{nums}[i]$ to the hash table $\textit{s}$ and continue to the next element.
89+
90+
After traversing, if no duplicate elements are found, the elements in the array are already distinct, and no operations are needed, so the answer is $0$.
91+
92+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $\textit{nums}$.
93+
94+
<!-- tabs:start -->
95+
96+
#### Python3
97+
98+
```python
99+
class Solution:
100+
def minimumOperations(self, nums: List[int]) -> int:
101+
s = set()
102+
for i in range(len(nums) - 1, -1, -1):
103+
if nums[i] in s:
104+
return i // 3 + 1
105+
s.add(nums[i])
106+
return 0
107+
```
108+
109+
#### Java
110+
111+
```java
112+
class Solution {
113+
public int minimumOperations(int[] nums) {
114+
Set<Integer> s = new HashSet<>();
115+
for (int i = nums.length - 1; i >= 0; --i) {
116+
if (s.contains(nums[i])) {
117+
return i / 3 + 1;
118+
}
119+
s.add(nums[i]);
120+
}
121+
return 0;
122+
}
123+
}
124+
```
125+
126+
#### C++
127+
128+
```cpp
129+
class Solution {
130+
public:
131+
int minimumOperations(vector<int>& nums) {
132+
unordered_set<int> s;
133+
for (int i = nums.size() - 1; ~i; --i) {
134+
if (s.contains(nums[i])) {
135+
return i / 3 + 1;
136+
}
137+
s.insert(nums[i]);
138+
}
139+
return 0;
140+
}
141+
};
142+
```
143+
144+
#### Go
145+
146+
```go
147+
func minimumOperations(nums []int) int {
148+
s := map[int]bool{}
149+
for i := len(nums) - 1; i >= 0; i-- {
150+
if s[nums[i]] {
151+
return i/3 + 1
152+
}
153+
s[nums[i]] = true
154+
}
155+
return 0
156+
}
157+
```
158+
159+
#### TypeScript
160+
161+
```ts
162+
function minimumOperations(nums: number[]): number {
163+
const s = new Set<number>();
164+
for (let i = nums.length - 1; ~i; --i) {
165+
if (s.has(nums[i])) {
166+
return Math.ceil((i + 1) / 3);
167+
}
168+
s.add(nums[i]);
169+
}
170+
return 0;
171+
}
172+
```
173+
174+
<!-- tabs:end -->
175+
176+
<!-- solution:end -->
177+
178+
<!-- problem:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Solution {
2+
public:
3+
int minimumOperations(vector<int>& nums) {
4+
unordered_set<int> s;
5+
for (int i = nums.size() - 1; ~i; --i) {
6+
if (s.contains(nums[i])) {
7+
return i / 3 + 1;
8+
}
9+
s.insert(nums[i]);
10+
}
11+
return 0;
12+
}
13+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
func minimumOperations(nums []int) int {
2+
s := map[int]bool{}
3+
for i := len(nums) - 1; i >= 0; i-- {
4+
if s[nums[i]] {
5+
return i/3 + 1
6+
}
7+
s[nums[i]] = true
8+
}
9+
return 0
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Solution {
2+
public int minimumOperations(int[] nums) {
3+
Set<Integer> s = new HashSet<>();
4+
for (int i = nums.length - 1; i >= 0; --i) {
5+
if (s.contains(nums[i])) {
6+
return i / 3 + 1;
7+
}
8+
s.add(nums[i]);
9+
}
10+
return 0;
11+
}
12+
}

0 commit comments

Comments
 (0)