如题~
给定一个正整数数组 A,如果 A 的某个子数组中不同整数的个数恰好为 K,则称 A 的这个连续、不一定独立的子数组为 好子数组。
(例如,[1,2,3,1,2] 中有 3 个不同的整数:1,2,以及 3。)
返回 A 中 好子数组 的数目。
示例 1:
输入:A = [1,2,1,2,3], K = 2
输出:7
解释:恰好由 2 个不同整数组成的子数组:[1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2].
示例 2:
输入:A = [1,2,1,3,4], K = 3
输出:3
解释:恰好由 3 个不同整数组成的子数组:[1,2,1,3], [2,1,3], [1,3,4].
用了个哈希表,双指针,滑动窗口。
毕竟这月前几天的题几乎一直没离开过滑动窗口。
class Solution {
public:
int windows(vector<int>& A, int K) {// 返回A中最多有K个不同数字的子数组个数
int n = A.size();
int left = 0, right = 0;//滑动窗口必备
int hash[25000] = {0};//来个哈希记录次数
int x = 0;
int res = 0;//答案
while (right < n)
{
if (hash[A[right]] == 0)//没出现过的数字
{
x++;
}
hash[A[right]]++;// 右指针指向的数字个数++
if (x <= K)//如果当前不同数字的种类小于K
{
res += right - left + 1;
}
else
{
while (x > K)// 如果当前不同数字的种类大于K,一直移动左边界
{
if (hash[A[left]] == 1)
{
x--;
}
hash[A[left]]--;
left++;
}
// 退出循环一定是 x == K ,所以这里要再次加一下子数组的个数
res += right - left + 1;
}
// 移动右指针
right++;
}
return res;
}
int subarraysWithKDistinct(vector<int>& A, int K) {
return windows(A, K) - windows(A, K - 1);
}
};