GuilinDev

Lc0992

05 August 2008

992. Subarrays with K Different Integers

给定一个正整数数组 A,如果 A 的某个子数组中不同整数的个数恰好为 K,则称 A 的这个连续、不一定不同的子数组为好子数组。

(例如,[1,2,3,1,2] 中有 3 个不同的整数:1,2,以及 3。)

返回 A 中好子数组的数目。

双指针(滑动窗口)

实现函数 atMostWithKDistinct(A, K) ,表示「最多存在 K 个不同整数的子区间的个数」。于是 atMostWithKDistinct(A, K) - atMostWithKDistinct(A, K - 1) 即为所求。

```java class Solution {

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public int subarraysWithKDistinct(int[] nums, int K) {
    return atMostKDistinct(nums, K) - atMostKDistinct(nums, K - 1);
}

/**
 * @param A
 * @param K
 * @return 最多包含 K 个不同整数的子区间的个数
 */
private int atMostKDistinct(int[] A, int K) {
    int len = A.length;
    int[] freq = new int[len + 1];

    int left = 0;
    int right = 0;
    // [left, right) 里不同整数的个数
    int count = 0;
    int result = 0;
    // [left, right) 包含不同整数的个数小于等于 K
    while (right < len) {
        if (freq[A[right]] == 0) {
            count++;
        }
        freq[A[right]]++;
        right++;

        while (count > K) {
            freq[A[left]]--;
            if (freq[A[left]] == 0) {
                count--;
            }
            left++;
        }
        // [left, right) 区间的长度就是对结果的贡献
        result += right - left;
    }
    return result;
} }