滑动窗口法的一般方案

一、主要思想

滑动窗口中用到了左右两个指针,它们移动的思路是:以右指针作为驱动,拖着左指针向前走。右指针每次只移动一步,而左指针在内部 while 循环中每次可能移动多步。右指针是主动前移,探索未知的新区域;左指针是被迫移动,负责寻找满足题意的区间。 

二、典型题目

给定一个由若干 01 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 。返回仅包含 1 的最长(连续)子数组的长度。

三、解题步骤

    1、定义两个指针 left 和 right 分别指向区间的开头和结尾,注意是闭区间;定义 sums 变量,用来统计该区间内的各个字符出现次数;
    2、第一重 while 循环是为了判断 right 指针的位置是否超出了数组边界;每当 right 每次到了新位置,需要增加 right 指针的求和/计数
    3、第二重 while 循环是让 left 指针向右移动到 [ left, right ] 区间符合题意的位置;当 left 每次移动到了新位置,需要减少 left 指针的求和/计数
    4、在第二重 while 循环之后,成功找到了一个符合题意的 [left, right] 区间,题目要求最大的区间长度,因此更新 res 为 max(res, 当前区间的长度) 。
    5、right 指针每次向右移动一步,开始探索新的区间。

四、伪代码

def findSubArray(nums):

    N = len(nums) # 数组/字符串长度

    left, right = 0, 0 # 双指针,表示当前遍历的区间[left, right]

    sums = 0 # 用于统计结果,根据题目可能会改成求和/计数

    res = 0 # 保存最大的满足题目要求的 子数组/子串 长度

    for right : N: # 遍历整个数组

        sums += nums[right] # 增加当前右边指针的数字/字符的求和/计数

        while 区间[left, right]不符合题意:# 此时需要一直移动左指针,直至找到一个符合题意的区间
            sums -= nums[left] # 移动左指针前需要从counter中减少left位置字符的求和/计数

            left += 1 # 真正的移动左指针,注意不能跟上面一行代码写反
        # 到 while 结束时,我们找到了一个符合题意要求的 子数组/子串

        res = max(res, right - left + 1) # 需要更新结果

        right += 1 # 移动右指针,去探索新的区间
    return res


五、实际代码 

class Solution {
public:
    int longestOnes(vector<int>& A, int K) {

        int res = 0, left = 0;
        int zeros = 0; // 0的个数

        for (int right = 0; right < A.size(); ++right) {

            if (A[right] == 0) ++zeros;

            while (zeros > K) { // 如果0的个数>K
                if (A[left++] == 0) --zeros; // 左指针右移,zeros同时减少一个
            }
            res = max(res, right - left + 1); // 计算最大连续1的个数
        }
        return res;
    }
};

参考:

https://leetcode-cn.com/problems/max-consecutive-ones-iii/solution/fen-xiang-hua-dong-chuang-kou-mo-ban-mia-f76z/

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值