力扣 992. K 个不同整数的子数组 思维 滑动窗口

181 篇文章 1 订阅
18 篇文章 0 订阅

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(k1)。那么对于这个子问题,我么能能否用滑动窗口来做呢?当然,考虑维护区间 [ l , r ) [l,r) [l,r)使得该区间内不同整数的个数最多为 k k k,那么这个区间对答案的贡献为 r − l r-l rl,为什么是这个数?因为在这个区间内以 r r r为右边界的子数组个数只有 r − l r-l rl个。

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值