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].
Note:
1 <= A.length <= 20000
1 <= A[i] <= A.length
1 <= K <= A.length
Key Observation:
1. The total number of such subarrays is the sum of the number of subarrays of K different integers that end at A[0], A[1], ..... A[n - 1].
2. Given an ending index i, the number of subarrays with K different integers that end at A[i] is the difference between the number of subarrays with <= K different integers and the number of subarrays with < K different integers. If we keep two running windows for these two cases <= K and < K, the count different is equivalent with the difference between the two left pointers of these two windows. (The right pointers are the same as both windows end at A[i]).
class Solution { private class Window { Mapcount; int distinctCnt; Window() { count = new HashMap(); distinctCnt = 0; } void add(int x) { count.put(x, count.getOrDefault(x, 0) + 1); if (count.get(x) == 1) { distinctCnt++; } } void remove(int x) { count.put(x, count.get(x) - 1); if (count.get(x) == 0) { distinctCnt--; } } int different() { return distinctCnt; } } public int subarraysWithKDistinct(int[] A, int K) { Window window1 = new Window(); Window window2 = new Window(); int ans = 0, left1 = 0, left2 = 0; for (int right = 0; right < A.length; ++right) { int x = A[right]; window1.add(x); window2.add(x); while (window1.different() > K) { window1.remove(A[left1]); left1++; } while (window2.different() >= K) { window2.remove(A[left2]); left2++; } ans += left2 - left1; } return ans; } }