Given an array A
of positive integers, call a (contiguous, not necessarily distinct) subarray of A
good if the number of different integers in that subarray is exactly K
.
(For example, [1,2,3,1,2]
has 3
different integers: 1
, 2
, and 3
.)
Return the number of good subarrays of A
.
Example 1:
Input: A = [1,2,1,2,3], K = 2
Output: 7
Explanation: 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].
Example 2:
Input: A = [1,2,1,3,4], K = 3
Output: 3
Explanation: Subarrays formed with exactly 3 different integers: [1,2,1,3], [2,1,3], [1,3,4].
思路:跟 Substrings with exactly K distinct chars ,把问题转换为 at most k的count,这样就好做,然后用公式f(k) - f(k-1); 为什么这么做转换,是因为 同向双指针是 j 一直往前面走,j不能回头的,但是这个题目要求是要求所有的 diff integer = k 的subarray;
[1,2,1,2] k = 2这个为例: [1,2], [1,2,1], [1,2,1,2], [2,1,2], [1,2] 都是答案,但是j没办法回去;所以计算是有问题的;所以不能单单扫一遍,是计算不出来的; res += j - i ; 代表的是以 j -1 为结尾的,满足at most k chars的个数;
class Solution {
public int subarraysWithKDistinct(int[] A, int K) {
if(A == null || A.length == 0) {
return 0;
}
return getAtMostK(A, K) - getAtMostK(A, K - 1);
}
private int getAtMostK(int[] A, int k) {
int res = 0;
int j = 0;
int count = 0;
int[] counts = new int[A.length + 1];
for(int i = 0; i < A.length; i++) {
// move j;
while(j < A.length && count <= k) {
if(counts[A[j]] == 0) {
if(count == k) {
break;
}
count++;
}
counts[A[j]]++;
j++;
}
// update result;
res += j - i;
// move i;
counts[A[i]]--;
if(counts[A[i]] == 0) {
count--;
}
}
return res;
}
}