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 };
原文地址:https://www.cnblogs.com/aaronliu1991/p/12630196.html
时间: 2024-11-03 16:26:33