Skip to content

Commit a00b5ae

Browse files
committed
feat: add weekly contest 503
1 parent a8cc312 commit a00b5ae

29 files changed

Lines changed: 2222 additions & 2 deletions

File tree

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
---
2+
comments: true
3+
difficulty: 简单
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3940.Limit%20Occurrences%20in%20Sorted%20Array/README.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3940. 限制有序数组中的元素出现次数](https://leetcode.cn/problems/limit-occurrences-in-sorted-array)
10+
11+
[English Version](/solution/3900-3999/3940.Limit%20Occurrences%20in%20Sorted%20Array/README_EN.md)
12+
13+
## 题目描述
14+
15+
<!-- description:start -->
16+
17+
<p>给你一个&nbsp;<strong>按升序排序&nbsp;</strong>的整数数组 <code>nums</code> 和一个整数 <code>k</code>。</p>
18+
19+
<p>返回一个数组,使得每个<strong>&nbsp;不同</strong>&nbsp;元素最多出现 <code>k</code> 次,同时保持 <code>nums</code> 中元素的相对顺序不变。</p>
20+
21+
<p>&nbsp;</p>
22+
23+
<p><strong class="example">示例 1:</strong></p>
24+
25+
<div class="example-block">
26+
<p><strong>输入:</strong> <span class="example-io">nums = [1,1,1,2,2,3], k = 2</span></p>
27+
28+
<p><strong>输出:</strong> <span class="example-io">[1,1,2,2,3]</span></p>
29+
30+
<p><strong>解释:</strong></p>
31+
32+
<p>每个元素最多可以出现 2 次。</p>
33+
34+
<ul>
35+
<li>元素 1 出现了 3 次,因此只保留其中 2 次。</li>
36+
<li>元素 2 出现了 2 次,因此全部保留。</li>
37+
<li>元素 3 出现了 1 次,因此保留。</li>
38+
</ul>
39+
40+
<p>因此,结果数组为 <code>[1, 1, 2, 2, 3]</code>。</p>
41+
</div>
42+
43+
<p><strong class="example">示例 2:</strong></p>
44+
45+
<div class="example-block">
46+
<p><strong>输入:</strong> <span class="example-io">nums = [1,2,3], k = 1</span></p>
47+
48+
<p><strong>输出:</strong> <span class="example-io">[1,2,3]</span></p>
49+
50+
<p><strong>解释:</strong></p>
51+
52+
<p>所有元素都互不相同,且已经最多只出现一次,因此数组保持不变。</p>
53+
</div>
54+
55+
<p>&nbsp;</p>
56+
57+
<p><strong>提示:</strong></p>
58+
59+
<ul>
60+
<li><code>1 &lt;= nums.length &lt;= 100</code></li>
61+
<li><code>1 &lt;= nums[i] &lt;= 100</code></li>
62+
<li><code>nums</code> 按非递减顺序排序。</li>
63+
<li><code>1 &lt;= k &lt;= nums.length</code></li>
64+
</ul>
65+
66+
<p>&nbsp;</p>
67+
68+
<p><strong>进阶:</strong></p>
69+
70+
<ul>
71+
<li>你能使用原地算法,并仅使用 <code>O(1)</code> 额外空间解决该问题吗?</li>
72+
<li>注意:用于返回结果或调整结果大小所占用的空间不计入上述空间复杂度,因为有些语言不支持原地调整数组大小。</li>
73+
</ul>
74+
75+
<!-- description:end -->
76+
77+
## 解法
78+
79+
<!-- solution:start -->
80+
81+
### 方法一:双指针
82+
83+
我们定义两个指针 $l$ 和 $r$,分别表示当前处理的元素和下一个要处理的元素。我们还定义一个计数器 $cnt$ 来记录当前元素出现的次数。初始时 $l$ 和 $cnt$ 都为 1。
84+
85+
然后,我们从 $r = 1$ 开始遍历数组:
86+
87+
1. 如果当前元素 $nums[r]$ 与前一个元素 $nums[r - 1]$ 不同,则说明我们遇到了一个新的元素,我们将计数器 $cnt$ 重置为 1。
88+
2. 如果当前元素 $nums[r]$ 与前一个元素 $nums[r - 1]$ 相同,则说明我们遇到了一个重复的元素,我们将计数器 $cnt$ 加 1。
89+
90+
如果计数器 $cnt$ 小于或等于 $k$,则说明当前元素出现的次数没有超过限制,我们将其保留在数组中,即将 $nums[l]$ 设置为 $nums[r]$,并将指针 $l$ 向右移动一位。
91+
92+
最后,我们返回数组的前 $l$ 个元素,即 $nums[:l]$。
93+
94+
时间复杂度 $O(n)$,其中 $n$ 是数组的长度。空间复杂度 $O(1)$,我们只使用了常数级别的额外空间。
95+
96+
<!-- tabs:start -->
97+
98+
#### Python3
99+
100+
```python
101+
class Solution:
102+
def limitOccurrences(self, nums: list[int], k: int) -> list[int]:
103+
n = len(nums)
104+
cnt = l = 1
105+
for r in range(1, n):
106+
if nums[r] != nums[r - 1]:
107+
cnt = 1
108+
else:
109+
cnt += 1
110+
if cnt <= k:
111+
nums[l] = nums[r]
112+
l += 1
113+
return nums[:l]
114+
```
115+
116+
#### Java
117+
118+
```java
119+
class Solution {
120+
public int[] limitOccurrences(int[] nums, int k) {
121+
int n = nums.length;
122+
int cnt = 1, l = 1;
123+
124+
for (int r = 1; r < n; r++) {
125+
if (nums[r] != nums[r - 1]) {
126+
cnt = 1;
127+
} else {
128+
cnt++;
129+
}
130+
131+
if (cnt <= k) {
132+
nums[l] = nums[r];
133+
l++;
134+
}
135+
}
136+
137+
return Arrays.copyOf(nums, l);
138+
}
139+
}
140+
```
141+
142+
#### C++
143+
144+
```cpp
145+
class Solution {
146+
public:
147+
vector<int> limitOccurrences(vector<int>& nums, int k) {
148+
int n = nums.size();
149+
int cnt = 1, l = 1;
150+
151+
for (int r = 1; r < n; r++) {
152+
if (nums[r] != nums[r - 1]) {
153+
cnt = 1;
154+
} else {
155+
cnt++;
156+
}
157+
158+
if (cnt <= k) {
159+
nums[l] = nums[r];
160+
l++;
161+
}
162+
}
163+
164+
nums.resize(l);
165+
return nums;
166+
}
167+
};
168+
```
169+
170+
#### Go
171+
172+
```go
173+
func limitOccurrences(nums []int, k int) []int {
174+
n := len(nums)
175+
cnt, l := 1, 1
176+
177+
for r := 1; r < n; r++ {
178+
if nums[r] != nums[r-1] {
179+
cnt = 1
180+
} else {
181+
cnt++
182+
}
183+
184+
if cnt <= k {
185+
nums[l] = nums[r]
186+
l++
187+
}
188+
}
189+
190+
return nums[:l]
191+
}
192+
```
193+
194+
#### TypeScript
195+
196+
```ts
197+
function limitOccurrences(nums: number[], k: number): number[] {
198+
const n = nums.length;
199+
let cnt = 1;
200+
let l = 1;
201+
202+
for (let r = 1; r < n; r++) {
203+
if (nums[r] !== nums[r - 1]) {
204+
cnt = 1;
205+
} else {
206+
cnt++;
207+
}
208+
209+
if (cnt <= k) {
210+
nums[l] = nums[r];
211+
l++;
212+
}
213+
}
214+
215+
return nums.slice(0, l);
216+
}
217+
```
218+
219+
<!-- tabs:end -->
220+
221+
<!-- solution:end -->
222+
223+
<!-- problem:end -->

0 commit comments

Comments
 (0)