https://leetcode-cn.com/problems/subarrays-with-k-different-integers/
思路:这个思维转换真的是妙啊。如果直接用滑动窗口来做的话,会发现结果对不上,会漏掉一些区间。那么我们可以考虑枚举子数组的长度,但是这样一来复杂度是
O
(
n
2
)
O(n^2)
O(n2),会超时。一般来说,使用滑动窗口的问题会有这种特性:最大、最多、最长。但是这道题是恰好,我们考虑把问题转换一下,假设
s
o
l
v
e
(
k
)
solve(k)
solve(k)可以求出不同整数的个数最多为
k
k
k的子数组个数,那么显然此题的答案就等于
s
o
l
v
e
(
k
)
−
s
o
l
v
e
(
k
−
1
)
solve(k)-solve(k-1)
solve(k)−solve(k−1)。那么对于这个子问题,我么能能否用滑动窗口来做呢?当然,考虑维护区间
[
l
,
r
)
[l,r)
[l,r)使得该区间内不同整数的个数最多为
k
k
k,那么这个区间对答案的贡献为
r
−
l
r-l
r−l,为什么是这个数?因为在这个区间内以
r
r
r为右边界的子数组个数只有
r
−
l
r-l
r−l个。
class Solution {
public:
int subarraysWithKDistinct(vector<int>& A, int K) {
return atMostkAnswer(A,K)-atMostkAnswer(A,K-1);
}
int atMostkAnswer(vector<int>& a,int k)
{
int n=a.size();
vector<int> cnt(n+1);
int ct=0,ans=0,l=0,r=0;
while(r<n)
{
if(++cnt[a[r++]]==1)
++ct;
while(ct>k)
{
if(--cnt[a[l++]]==0)
--ct;
}
ans+=r-l;
}
return ans;
}
};