leetcode1004 [最大连续1的个数 III]

给定一个由若干 01 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 。

返回仅包含 1 的最长(连续)子数组的长度。

1.题意是要返回 1 的最长连续子数组的长度 连续 就可以想到窗口了

最多可以把k个0转化成1。

解决主要思想就是:一开始维护一个0小于k的窗口,右指针不断向右遍历,如果窗口中0的个数>k(也就是0的个数为k+1时),移动左指针,窗口不断变小,直到窗口中0的个数等于k,左指针停止移动,继续移动右指针。

题意就可以转化为 如果当前的窗口的左边界是l,右边界是right。

假设 K > 0; l = 0, r = 0开始。

假设窗口内的0是小于等于k的。

r向右遍历,如果nums[r] == 0, 判断 一下当前窗口中的个数是否>K

  1. 如果 >k ,移动左指针减少0的个数,直到窗口中的0的个数为k时停止,更新答案继续移动右指针。

  1. <=k 更新答案继续移动右指针。

 public int longestOnes(int[] nums, int k) {
        int n = nums.length;
        int l = 0,r = 0;
        int ans = 0;
        int sum = 0;
        while(r < n){
            sum += (1- nums[r]);
            while(sum > k){
                sum -= (1-nums[l++]);
            }
            
            ans = Math.max(ans,++r-l);
        }
        return ans;
        
    }

  1. 因为题意只是让我们找最长连续子区间的长度,如果我当前的最长子序列长度已经为m了,那么小于m的区间就不用再去看是否满足条件了。看>m的连续子序列长度是否有满足条件的

    
  public int longestOnes(int[] nums, int k) {
        int n = nums.length;
          // 此时长度为r-l == 0 
        int l = 0,r = 0;
​
        int sum = 0;
        while(r < n){
            // 1. 满足0的个数<=k  直接r++;
            // 2. 0的个数>k  此时最小子区间为[l,r-1],长度为r-l了,比这个长度小的就不用再去检查0的个数是否小于等于k了  l++ 如果nums[l] == 0 sum--; nums[l] == 1,sum不变,保证区间长度等于m。   这是一种贪心的思想,长度已经不可能比m小了,在 一次sum += (1- nums[r++]); 一次 sum -= (1-nums[l++]);if sum <=k ,l就停止不动了  r继续++ 此时长度会比m更大
            sum += (1- nums[r++]);
            if(sum > k){
                sum -= (1-nums[l++]);
            }
            
        
        }
          
         // r - l 代表的是从[0,r]中的1的最长连续子区间的长度 r-l不会减小,只会增大,最后返回的这个肯定为最大值  贪心的思想  省去每次r++需要重新计算最长连续子区间的长度的步骤
        return r-l;
        
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值