leetcode1004题解,最简单的滑动窗口写法

今天做了头条笔试题,又是惨淡而归,一道不会,然后有人告诉我最后一道题是leetcode原题,看了之后,理解了普通的滑动窗口的解法,然后看了高赞的解答,感觉好精简的说,想了好久才想明白,这里解释一下高赞的解答。原题如下:
在这里插入图片描述
在这里插入图片描述
普通滑动窗口的Java代码如下(很容易理解,不解释):

    public int longestOnes(int[] A, int K) {
        
        int len = A.length, l = 0, num = 0, res = 0;
        for(int r = 0; r < len; r++) {
            if(A[r] == 0) {
                num++;
            }
            while(num > K) {
                if(A[l] == 0) {
                    num--;
                }
                l++;
            }
            res = Math.max(res, r - l + 1);
        }
        return res;
        
    }

高赞解答的Java代码如下:

    public int longestOnes(int[] A, int K) {
        int i = 0, j;
        for (j = 0; j < A.length; ++j) {
            if (A[j] == 0) K--;
            if (K < 0 && A[i++] == 0) K++;
        }
        return j - i;
    }
    

看到这个代码,我的第一反应是这么简单?还可以这么写?然后就开始想为什么这么写,其实最重要的思想就是,窗口有两个变化趋势:第一个是,当K>=0时,长度增1,即j++,第二个是,当K<0时,长度不变,即j++,i++。i和j所确定的窗口不一定是最长的合法窗口,显然不可能所有的最长1区间都出现在尾部,但却一定和目前为止最长合法窗口的长度相等,因为它是从合法窗口移动过来的。最后为什么不是j-i+1呢?因为j会出界,而i不会,所以就不需要加1了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值