Input: nums =[1,2,1,2,3], k =2Output: 7Explanation: Subarrays formed with exactly 2 different integers:[1,2],[2,1],[1,2],[2,3],[1,2,1],[2,1,2],[1,2,1,2]
The number of subarrays with exactly K different integers is equal to the number with at most K minus the number with at most K-1. We can use a sliding window to count subarrays with at most K different integers efficiently.
#include<vector>#include<unordered_map>usingnamespace std;
classSolution {
intatMostK(vector<int>& nums, int K) {
unordered_map<int, int> count;
int res =0, left =0;
for (int right =0; right < nums.size(); ++right) {
if (++count[nums[right]] ==1) --K;
while (K <0) {
if (--count[nums[left++]] ==0) ++K;
}
res += right - left +1;
}
return res;
}
public:int subarraysWithKDistinct(vector<int>& nums, int K) {
returnatMostK(nums, K) - atMostK(nums, K-1);
}
};
import java.util.*;
classSolution {
publicintsubarraysWithKDistinct(int[] nums, int K) {
return atMostK(nums, K) - atMostK(nums, K-1);
}
privateintatMostK(int[] nums, int K) {
Map<Integer, Integer> count =new HashMap<>();
int res = 0, left = 0;
for (int right = 0; right < nums.length; ++right) {
count.put(nums[right], count.getOrDefault(nums[right], 0) + 1);
if (count.get(nums[right]) == 1) --K;
while (K < 0) {
count.put(nums[left], count.get(nums[left]) - 1);
if (count.get(nums[left]) == 0) ++K;
left++;
}
res += right - left + 1;
}
return res;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
funsubarraysWithKDistinct(nums: IntArray, K: Int): Int {
funatMostK(K: Int): Int {
val count = mutableMapOf<Int, Int>()
var res = 0; var left = 0for (right in nums.indices) {
count[nums[right]] = count.getOrDefault(nums[right], 0) + 1if (count[nums[right]] ==1) K--while (K < 0) {
count[nums[left]] = count[nums[left]]!! - 1if (count[nums[left]] ==0) K++ left++ }
res += right - left + 1 }
return res
}
return atMostK(K) - atMostK(K-1)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
defsubarraysWithKDistinct(nums, K):
defatMostK(K):
count = {}
res = left =0for right, v in enumerate(nums):
count[v] = count.get(v, 0) +1if count[v] ==1:
K -=1while K <0:
count[nums[left]] -=1if count[nums[left]] ==0:
K +=1 left +=1 res += right - left +1return res
return atMostK(K) - atMostK(K-1)