Skip to content

滑动窗口

滑动窗口也叫做“同向双指针”

适用条件:

  1. 单调的(比如都是正数)
  2. 针对于一个小区间内判断
  3. 左边界与右边界是向相同方向移动

解题步骤:

  1. 定义 leftright,令它们的值为 0
  2. 进窗口right++
  3. 判断一下,如果满足条件出窗口left++
  4. 根据题目需要,更新结果

LC209. 长度最小的子数组

思路:

  1. 分析题目,发现全是正数,而且是在一个区间内进行操作,就要想到滑动窗口
  2. 进窗口,计算区间内的总和
  3. 判断总和是否大于目标值,如果大于,那么记录一下当前长度,并且判断一下要不要更新结果
  4. 出窗口,再次计算总和
  5. 重复 2/3/4 循环,直到遍历结束
步骤: 0 / 0

当前动作:等待输入...

LC3. 无重复字符的最长子串

观察题目:发现有子串,可能会用到滑动窗口

画图:通过观察,发现 leftright 可以同时向右移动,那么就要想到滑动窗口了(重点)

思路:

  1. 获取右边字符,rightV,接着判断哈希表内也没有包含 rightV
  2. 如果不包含,那么就直接到下一个
  3. 如果包含,那么就要获取到左边字符 leftV,判断是否与右边相等,如果不相等那么就一直删除哈希表中的 leftV
步骤: 0 / 0

当前动作:等待输入...

LC1004. 最大连续1的个数 III

思路:

  1. 定义 leftright,如果 right 的值 rV != 0 的情况下,那么就只需要 right++ 即可
  2. 如果 rV == 0,那么在之前的基础上判断 k 是否等于 0
    1. k != 0, 说明还可以把 0 翻转为 1, 那么就可以右移,不过需要 k--
    2. k == 0, 说明已经当前已经是最长的了,计算长度,保留最大值,接着将 left 右移,直到遇到值为 0 的情况才能停下来, 然后 left 跳过值为 0, k++
步骤: 0 / 0

当前动作:等待输入...

LC1658. 将 x 减到 0 的最小操作数

背景:

  1. sum[left, right) 这个区间内的总和
  2. sumTotal 是数组 nums 所有元素的和

思路:

  1. 读取题目,发现如果按照题目的方式做,那么是很困难的,因此要想到正难则反
    1. 题目中是求左右两边的和为 x,这个可以转换为求中间区间的和 sum,然后用 sumTotal - sum 这个值与 x 判断即可
    2. 这样可以把两个区间求和变成一个区间求和,难度递减
  2. 这样就可以转变为长度最小的子数组类似的题目了:求 sumtarget(sumTotal - x) 关系即可
步骤: 0 / 0

当前动作:等待输入...

LC904. 水果成篮

读题目,题目的意思就是:求最长的连续子数组,要求里面元素的类似不超过2

思路(暴力枚举):

  1. 遍历每个子数组,判断是否包含两种极其一下的数据
  2. 如果包含,那么就 right++
  3. 如果不包含,那么就记录并更新当前长度,接着 left++, right 重新遍历(优化点)

思路(优化): 把“暴力枚举”的第3步优化一下,发现 right 不需要重新遍历,因为

left++ 之前,[left, right] 区间内就已经是符合条件的, left++ 后,元素少一个那一定依然是符合条件的

步骤: 0 / 0

当前动作:等待输入...

LC438. 找到字符串中所有字母异位词

思路:

  1. “异位词”判断:首先发现它不需要顺序,其次判断内部的值是否相等,那么就可以用 hash 表来判断,而不是通过排序来判断
  2. 找到“异位词”,是找连续的区间,并且长度是与目标异位词相等,那么它左边与右边都是向右侧移动,就要想到滑动窗口

判断逻辑优化:

  • 不要遍历hash表来判断,通过 totalValidCount 来判断,它是用来统计当前数组的有效数据的个数
  • totalValidCount 更新:totalValidCount 加上 当前索引更新后的有效数据 - 当前索引更新前的有效数据
  • 当前索引的有效数据获取:获取 pHashsHash 的对应索引的较小值即可
步骤: 0 / 0

当前动作:等待输入...

LC30. 串联所有单词的子串

思路:words 中的 word 看为字符为 1 的词,把 s 中各个子串也看为字符为 1 的词, 那么就和 找到字符串中所有字母异位词 的一样,都是不要求顺序,只找包含的内容

细节:

  1. 滑动窗口执行的次数与 word 的长度一致
  2. leftright 的步长也与 word 长度一致
步骤: 0 / 0

当前动作:等待输入...

LC376. 最小覆盖子串

观察题目,发现是找连续的子串,要想到可能是涉及滑动窗口

问题思考:假设 [left, right] 是满足条件的区间,那么 left 右移后,right 需不需要重新从左开始移动呢?

不需要(leftright 同时向右移动,那么就可以用滑动窗口了)

  1. 如果 [left + 1, right] 满足,那 right 不需要移动
  2. 如果 [left + 1, right] 不满足条件,那么 right 是需要向右边移动
步骤: 0 / 0

当前动作:等待输入...