滑动窗口3:1004. 最大连续1的个数 III

链接:1004. 最大连续1的个数 III - 力扣(LeetCode)

题解:

滑动窗口基本解题思路:

  • 进窗口
  • 判断
  • 出窗口
  • 更新结果(该步骤顺序不固定,可能在进窗口时更新结果,也可能在判断成立时更新结果,也有可能在判断条件结束之后更新结果)

滑动窗口本质上是从暴力解法优化而来的,本题本质上就是查找0个数不超过k的最大子串,暴力算法就是枚举出所有字串,并从中筛选出0个数不超过k的所有子串,取最大的子串。

优化1:暴力算法以某个元素为开头枚举子串时,如果枚举到0个数已经超过k的子串了,那么就没有必要继续向后枚举了,因为接下来的所有以该元素开头的子串中0的个数一定都是超过k的,可以直接进入下一轮枚举,以下一个元素作为字串开头来枚举。例如有数组: [1,1,1,0,0,0,1,1,1,1,0],k=2,枚举到子串111000时,0的个数超过k,继续向后枚举1110001、11100011等的所有子串中0的个数都是超过k的。

优化2:以下一个元素作为子串开头,进入下一轮枚举时,也没有必要从从头开始枚举,例如有数组:[0,1,1,0,0,0,1,1,1,1,0],k=2,当枚举到子串01100时,0的个数超过了k,直接进行下一轮枚举从第二个元素1开始枚举,直接从1100开始枚举,因为我们已经知道01100中有几个0了,进行下一轮枚举时仅仅是相当于去除了原本的首元素,所以可以根据首元素是否为0计算剩下的子串中0的个数。

class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int ans=INT_MIN;
        int n=nums.size();
        int flag=0;

        for(int left=0,right=0;right<n;right++)
        {
            if(nums[right]==0) flag+=1;//进窗口
            while(flag>k)//判断
            {
                if(nums[left]==0) flag-=1;//出窗口
                left++;
            }
            ans=max(ans,right-left+1);//更新结果
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南林yan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值