Skip to content

Commit 421acf1

Browse files
committed
feat: add solutions to lc problem: No.0992
No.0992.Subarrays with K Different Integers
1 parent af1410f commit 421acf1

File tree

9 files changed

+349
-5
lines changed

9 files changed

+349
-5
lines changed

solution/0900-0999/0992.Subarrays with K Different Integers/README.md

+125-1
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,146 @@
4747

4848
<!-- 这里可写通用的实现逻辑 -->
4949

50+
**方法一:双指针**
51+
52+
我们遍历数组 $nums$,对于每个 $i$,我们需要找到最小的 $j_1$,使得 $nums[j_1], nums[j_1 + 1], \dots, nums[i]$ 中不同的整数个数小于等于 $k$,以及最小的 $j_2$,使得 $nums[j_2], nums[j_2 + 1], \dots, nums[i]$ 中不同的整数个数小于等于 $k-1$。那么 $j_2 - j_1$ 就是以 $i$ 结尾的满足条件的子数组的个数。
53+
54+
在实现上,我们定义一个函数 $f(k)$,表示 $nums$ 中每个位置 $i$ 对应的最小的 $j$,使得 $nums[j], nums[j + 1], \dots, nums[i]$ 中不同的整数个数小于等于 $k$。该函数可以通过双指针实现,具体实现见代码。
55+
56+
然后我们调用 $f(k)$ 和 $f(k-1)$,计算出每个位置对应的 $j_1$ 和 $j_2$,然后计算出以每个位置 $i$ 结尾的满足条件的子数组的个数,最后求和即可。
57+
58+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
59+
5060
<!-- tabs:start -->
5161

5262
### **Python3**
5363

5464
<!-- 这里可写当前语言的特殊实现逻辑 -->
5565

5666
```python
57-
67+
class Solution:
68+
def subarraysWithKDistinct(self, nums: List[int], k: int) -> int:
69+
def f(k):
70+
pos = [0] * len(nums)
71+
cnt = Counter()
72+
j = 0
73+
for i, x in enumerate(nums):
74+
cnt[x] += 1
75+
while len(cnt) > k:
76+
cnt[nums[j]] -= 1
77+
if cnt[nums[j]] == 0:
78+
cnt.pop(nums[j])
79+
j += 1
80+
pos[i] = j
81+
return pos
82+
83+
return sum(a - b for a, b in zip(f(k - 1), f(k)))
5884
```
5985

6086
### **Java**
6187

6288
<!-- 这里可写当前语言的特殊实现逻辑 -->
6389

6490
```java
91+
class Solution {
92+
public int subarraysWithKDistinct(int[] nums, int k) {
93+
int[] left = f(nums, k);
94+
int[] right = f(nums, k - 1);
95+
int ans = 0;
96+
for (int i = 0; i < nums.length; ++i) {
97+
ans += right[i] - left[i];
98+
}
99+
return ans;
100+
}
101+
102+
private int[] f(int[] nums, int k) {
103+
int n = nums.length;
104+
int[] cnt = new int[n + 1];
105+
int[] pos = new int[n];
106+
int s = 0;
107+
for (int i = 0, j = 0; i < n; ++i) {
108+
if (++cnt[nums[i]] == 1) {
109+
++s;
110+
}
111+
for (; s > k; ++j) {
112+
if (--cnt[nums[j]] == 0) {
113+
--s;
114+
}
115+
}
116+
pos[i] = j;
117+
}
118+
return pos;
119+
}
120+
}
121+
```
122+
123+
### **C++**
124+
125+
```cpp
126+
class Solution {
127+
public:
128+
int subarraysWithKDistinct(vector<int>& nums, int k) {
129+
vector<int> left = f(nums, k);
130+
vector<int> right = f(nums, k - 1);
131+
int ans = 0;
132+
for (int i = 0; i < nums.size(); ++i) {
133+
ans += right[i] - left[i];
134+
}
135+
return ans;
136+
}
137+
138+
vector<int> f(vector<int>& nums, int k) {
139+
int n = nums.size();
140+
vector<int> pos(n);
141+
int cnt[n + 1];
142+
memset(cnt, 0, sizeof(cnt));
143+
int s = 0;
144+
for (int i = 0, j = 0; i < n; ++i) {
145+
if (++cnt[nums[i]] == 1) {
146+
++s;
147+
}
148+
for (; s > k; ++j) {
149+
if (--cnt[nums[j]] == 0) {
150+
--s;
151+
}
152+
}
153+
pos[i] = j;
154+
}
155+
return pos;
156+
}
157+
};
158+
```
65159

160+
### **Go**
161+
162+
```go
163+
func subarraysWithKDistinct(nums []int, k int) (ans int) {
164+
f := func(k int) []int {
165+
n := len(nums)
166+
pos := make([]int, n)
167+
cnt := make([]int, n+1)
168+
s, j := 0, 0
169+
for i, x := range nums {
170+
cnt[x]++
171+
if cnt[x] == 1 {
172+
s++
173+
}
174+
for ; s > k; j++ {
175+
cnt[nums[j]]--
176+
if cnt[nums[j]] == 0 {
177+
s--
178+
}
179+
}
180+
pos[i] = j
181+
}
182+
return pos
183+
}
184+
left, right := f(k), f(k-1)
185+
for i := range left {
186+
ans += right[i] - left[i]
187+
}
188+
return
189+
}
66190
```
67191

68192
### **...**

solution/0900-0999/0992.Subarrays with K Different Integers/README_EN.md

+115-1
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,127 @@
4646
### **Python3**
4747

4848
```python
49-
49+
class Solution:
50+
def subarraysWithKDistinct(self, nums: List[int], k: int) -> int:
51+
def f(k):
52+
pos = [0] * len(nums)
53+
cnt = Counter()
54+
j = 0
55+
for i, x in enumerate(nums):
56+
cnt[x] += 1
57+
while len(cnt) > k:
58+
cnt[nums[j]] -= 1
59+
if cnt[nums[j]] == 0:
60+
cnt.pop(nums[j])
61+
j += 1
62+
pos[i] = j
63+
return pos
64+
65+
return sum(a - b for a, b in zip(f(k - 1), f(k)))
5066
```
5167

5268
### **Java**
5369

5470
```java
71+
class Solution {
72+
public int subarraysWithKDistinct(int[] nums, int k) {
73+
int[] left = f(nums, k);
74+
int[] right = f(nums, k - 1);
75+
int ans = 0;
76+
for (int i = 0; i < nums.length; ++i) {
77+
ans += right[i] - left[i];
78+
}
79+
return ans;
80+
}
81+
82+
private int[] f(int[] nums, int k) {
83+
int n = nums.length;
84+
int[] cnt = new int[n + 1];
85+
int[] pos = new int[n];
86+
int s = 0;
87+
for (int i = 0, j = 0; i < n; ++i) {
88+
if (++cnt[nums[i]] == 1) {
89+
++s;
90+
}
91+
for (; s > k; ++j) {
92+
if (--cnt[nums[j]] == 0) {
93+
--s;
94+
}
95+
}
96+
pos[i] = j;
97+
}
98+
return pos;
99+
}
100+
}
101+
```
102+
103+
### **C++**
104+
105+
```cpp
106+
class Solution {
107+
public:
108+
int subarraysWithKDistinct(vector<int>& nums, int k) {
109+
vector<int> left = f(nums, k);
110+
vector<int> right = f(nums, k - 1);
111+
int ans = 0;
112+
for (int i = 0; i < nums.size(); ++i) {
113+
ans += right[i] - left[i];
114+
}
115+
return ans;
116+
}
117+
118+
vector<int> f(vector<int>& nums, int k) {
119+
int n = nums.size();
120+
vector<int> pos(n);
121+
int cnt[n + 1];
122+
memset(cnt, 0, sizeof(cnt));
123+
int s = 0;
124+
for (int i = 0, j = 0; i < n; ++i) {
125+
if (++cnt[nums[i]] == 1) {
126+
++s;
127+
}
128+
for (; s > k; ++j) {
129+
if (--cnt[nums[j]] == 0) {
130+
--s;
131+
}
132+
}
133+
pos[i] = j;
134+
}
135+
return pos;
136+
}
137+
};
138+
```
55139

140+
### **Go**
141+
142+
```go
143+
func subarraysWithKDistinct(nums []int, k int) (ans int) {
144+
f := func(k int) []int {
145+
n := len(nums)
146+
pos := make([]int, n)
147+
cnt := make([]int, n+1)
148+
s, j := 0, 0
149+
for i, x := range nums {
150+
cnt[x]++
151+
if cnt[x] == 1 {
152+
s++
153+
}
154+
for ; s > k; j++ {
155+
cnt[nums[j]]--
156+
if cnt[nums[j]] == 0 {
157+
s--
158+
}
159+
}
160+
pos[i] = j
161+
}
162+
return pos
163+
}
164+
left, right := f(k), f(k-1)
165+
for i := range left {
166+
ans += right[i] - left[i]
167+
}
168+
return
169+
}
56170
```
57171

58172
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class Solution {
2+
public:
3+
int subarraysWithKDistinct(vector<int>& nums, int k) {
4+
vector<int> left = f(nums, k);
5+
vector<int> right = f(nums, k - 1);
6+
int ans = 0;
7+
for (int i = 0; i < nums.size(); ++i) {
8+
ans += right[i] - left[i];
9+
}
10+
return ans;
11+
}
12+
13+
vector<int> f(vector<int>& nums, int k) {
14+
int n = nums.size();
15+
vector<int> pos(n);
16+
int cnt[n + 1];
17+
memset(cnt, 0, sizeof(cnt));
18+
int s = 0;
19+
for (int i = 0, j = 0; i < n; ++i) {
20+
if (++cnt[nums[i]] == 1) {
21+
++s;
22+
}
23+
for (; s > k; ++j) {
24+
if (--cnt[nums[j]] == 0) {
25+
--s;
26+
}
27+
}
28+
pos[i] = j;
29+
}
30+
return pos;
31+
}
32+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
func subarraysWithKDistinct(nums []int, k int) (ans int) {
2+
f := func(k int) []int {
3+
n := len(nums)
4+
pos := make([]int, n)
5+
cnt := make([]int, n+1)
6+
s, j := 0, 0
7+
for i, x := range nums {
8+
cnt[x]++
9+
if cnt[x] == 1 {
10+
s++
11+
}
12+
for ; s > k; j++ {
13+
cnt[nums[j]]--
14+
if cnt[nums[j]] == 0 {
15+
s--
16+
}
17+
}
18+
pos[i] = j
19+
}
20+
return pos
21+
}
22+
left, right := f(k), f(k-1)
23+
for i := range left {
24+
ans += right[i] - left[i]
25+
}
26+
return
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class Solution {
2+
public int subarraysWithKDistinct(int[] nums, int k) {
3+
int[] left = f(nums, k);
4+
int[] right = f(nums, k - 1);
5+
int ans = 0;
6+
for (int i = 0; i < nums.length; ++i) {
7+
ans += right[i] - left[i];
8+
}
9+
return ans;
10+
}
11+
12+
private int[] f(int[] nums, int k) {
13+
int n = nums.length;
14+
int[] cnt = new int[n + 1];
15+
int[] pos = new int[n];
16+
int s = 0;
17+
for (int i = 0, j = 0; i < n; ++i) {
18+
if (++cnt[nums[i]] == 1) {
19+
++s;
20+
}
21+
for (; s > k; ++j) {
22+
if (--cnt[nums[j]] == 0) {
23+
--s;
24+
}
25+
}
26+
pos[i] = j;
27+
}
28+
return pos;
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution:
2+
def subarraysWithKDistinct(self, nums: List[int], k: int) -> int:
3+
def f(k):
4+
pos = [0] * len(nums)
5+
cnt = Counter()
6+
j = 0
7+
for i, x in enumerate(nums):
8+
cnt[x] += 1
9+
while len(cnt) > k:
10+
cnt[nums[j]] -= 1
11+
if cnt[nums[j]] == 0:
12+
cnt.pop(nums[j])
13+
j += 1
14+
pos[i] = j
15+
return pos
16+
17+
return sum(a - b for a, b in zip(f(k - 1), f(k)))

solution/2500-2599/2586.Count the Number of Vowel Strings in Range/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656

5757
**方法一:模拟**
5858

59-
我们只需要遍历区间 `[left, right]` 内的字符串,判断其是否以元音字母开头和结尾即可。若是,则答案加一。
59+
我们只需要遍历区间 $[left,.. right]$ 内的字符串,判断其是否以元音字母开头和结尾即可。若是,则答案加一。
6060

6161
遍历结束后,返回答案即可。
6262

0 commit comments

Comments
 (0)