[LeetCode, not perfect] 992. Subarrays with K Different Integers

K个不同整数的子数组。题意是给定一个正整数数组 A,如果 A 的某个子数组中不同整数的个数恰好为 K,则称 A 的这个连续、不一定独立的子数组为好子数组。返回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].

思路依然是滑动窗口,但是这一题我只理解一个没有普适性的解法,之后再做修正。回忆前面做的滑动窗口的题目,有求过子数组里面最多K个不同元素的题(340),所以这个解法的思路是求子数组里面最多K个不同元素的子数组的数量子数组里面最多K - 1个不同元素的子数组的数量。如果理解这个思路是怎么来的,代码就非常简单了,直接套用之前的模板即可。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public int subarraysWithKDistinct(int[] A, int K) {
 3         return atMostK(A, K) - atMostK(A, K - 1);
 4     }
 5 
 6     private int atMostK(int[] A, int K) {
 7         int i = 0;
 8         int res = 0;
 9         Map<Integer, Integer> map = new HashMap<>();
10         for (int j = 0; j < A.length; j++) {
11             if (map.getOrDefault(A[j], 0) == 0) {
12                 K--;
13             }
14             map.put(A[j], map.getOrDefault(A[j], 0) + 1);
15             while (K < 0) {
16                 map.put(A[i], map.get(A[i]) - 1);
17                 if (map.get(A[i]) == 0) {
18                     K++;
19                 }
20                 i++;
21             }
22             res += j - i + 1;
23         }
24         return res;
25     }
26 }

JavaScript实现

 1 /**
 2  * @param {number[]} A
 3  * @param {number} K
 4  * @return {number}
 5  */
 6 var subarraysWithKDistinct = function (A, K) {
 7     function atMostK(k) {
 8         let l = 0;
 9         let res = 0;
10         const count = {};
11 
12         for (let r = 0; r < A.length; r++) {
13             if (count[A[r]] == null) count[A[r]] = 0;
14             if (count[A[r]] === 0) k--;
15             count[A[r]]++;
16 
17             while (k < 0) {
18                 count[A[l]]--;
19                 if (count[A[l]] === 0) k++;
20                 l++;
21             }
22             res += r - l + 1;
23         }
24         return res;
25     }
26     return atMostK(K) - atMostK(K - 1);
27 };

猜你喜欢

转载自www.cnblogs.com/aaronliu1991/p/12630196.html