[滑动窗口]leetcode992:K个不同整数的子数组(hard)

题目:
在这里插入图片描述
题解:

本题的难点在于思考[1,2,1,2,3]中的[2,1],[2,1,2],[1,2]这些子数组是如何求出来的,对于[1,2],[1,2,1],[1,2,1,2],[2,3]这些子数组求解可以利用window的size为k时求出。
当window的size等于k时,也就是window内有k个不同的整数,我们求出[left,right]这个区间的窗口内还有多少个满足题目条件的子数组。注意:这里的子数组必须是以right结尾的子数组。
比如:

  • [1,2,1]中以window[right]结尾的子数组还有[2,1]
  • [1,2,1,2]中以window[right]结尾的子数组还有[2,1,2],[1,2]

代码如下:

class Solution {
public:
    int subarraysWithKDistinct(vector<int>& A, int K) {
        if(A.empty()||K==0)return 0;
        
        int left=0,right=0,result=0,N=A.size();
        unordered_map<int,int> window;//窗口:K个数字->每个数字出现的次数
        
        while(right<N)
        {
            window[A[right++]]++;
            
            while(window.size()>K)//窗口溢出,需缩小窗口
            {
                if(window[A[left]]>1)window[A[left]]--;
                else window.erase(A[left]);
                left++;
            }
            
            int temp=left;//用来求必须以A[right]结尾的子数组满足题目条件的个数,对left不会产生影响。
            //必须以A[right]=2结尾的子数组个数,比如[1,2,1,2]中满足题目条件的子数组有[2,1,2] [1,2]
            while(window.size()==K)//子数组中有K个不同的整数,来更新result
            {
                result++;
                if(window[A[temp]]>1)window[A[temp]]--;
                else window.erase(A[temp]);
                temp++;
            }
            
            while(temp>left)//还原子数组
            {
                window[A[temp-1]]++;
                temp--;
            }
        }
        
        return result;
    }
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值