前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文带你AC十道题【滑动窗口】

一文带你AC十道题【滑动窗口】

作者头像
lucifer210
发布2020-03-18 10:53:46
1.2K0
发布2020-03-18 10:53:46
举报
文章被收录于专栏:脑洞前端脑洞前端脑洞前端

笔者最早接触滑动窗口是滑动窗口协议,滑动窗口协议(Sliding Window Protocol),属于 TCP 协议的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生。发送方和接收方分别有一个窗口大小 w1 和 w2。窗口大小可能会根据网络流量的变化而有所不同,但是在更简单的实现中它们是固定的。窗口大小必须大于零才能进行任何操作。

我们算法中的滑动窗口也是类似,只不过包括的情况更加广泛。实际上上面的滑动窗口在某一个时刻就是固定窗口大小的滑动窗口,随着网络流量等因素改变窗口大小也会随着改变。接下来我们讲下算法中的滑动窗口。

介绍

滑动窗口是一种解决问题的思路和方法,通常用来解决一些连续问题。比如 LeetCode 的 209. 长度最小的子数组。更多滑动窗口题目见下方题目列表

常见套路

滑动窗口主要用来处理连续问题。比如题目求解“连续子串 xxxx”,“连续子数组 xxxx”,就应该可以想到滑动窗口。能不能解决另说,但是这种敏感性还是要有的。

从类型上说主要有:

  • 固定窗口大小
  • 窗口大小不固定,求解最大的满足条件的窗口
  • 窗口大小不固定,求解最小的满足条件的窗口(上面的 209 题就属于这种)

后面两种我们统称为可变窗口。当然不管是哪种类型基本的思路都是一样的,不一样的仅仅是代码细节。

固定窗口大小

对于固定窗口,我们只需要固定初始化左右指针 l 和 r,分别表示的窗口的左右顶点,并且保证:

  1. l 初始化为 0
  2. 初始化 r,使得 r - l + 1 等于窗口大小
  3. 同时移动 l 和 r
  4. 判断窗口内的连续元素是否满足题目限定的条件
    • 4.1 如果满足,再判断是否需要更新最优解,如果需要则更新最优解
    • 4.2 如果不满足,则继续。

可变窗口大小

对于可变窗口,我们同样固定初始化左右指针 l 和 r,分别表示的窗口的左右顶点。后面有所不同,我们需要保证:

  1. l 和 r 都初始化为 0
  2. r 指针移动一步
  3. 判断窗口内的连续元素是否满足题目限定的条件
    • 4.1 如果满足,再判断是否需要更新最优解,如果需要则更新最优解。并尝试通过移动 l 指针缩小窗口大小。循环执行 4.1
    • 4.2 如果不满足,则继续。

形象地来看的话,就是 r 指针不停向右移动,l 指针仅仅在窗口满足条件之后才会移动,起到窗口收缩的效果。

模板代码

以下是 209 题目的代码,使用 Python 编写,大家意会即可。

class Solution:
    def minSubArrayLen(self, s: int, nums: List[int]) -> int:
        l = total = 0
        ans = len(nums) + 1
        for r in range(len(nums)):
            total += nums[r]
            while total >= s:
                ans = min(ans, r - l + 1)
                total -= nums[l]
                l += 1
        return  0 if ans == len(nums) + 1 else ans

题目列表

以下题目有的信息比较直接,有的题目信息比较隐蔽,需要自己发掘

  • 【Python,JavaScript】滑动窗口(3. 无重复字符的最长子串)[1]
  • 76. 最小覆盖子串[2]
  • 209. 长度最小的子数组[3]
  • 【Python】滑动窗口(438. 找到字符串中所有字母异位词)[4]
  • 【904. 水果成篮】(Python3)[5]
  • 【930. 和相同的二元子数组】(Java,Python)[6]
  • 【992. K 个不同整数的子数组】滑动窗口(Python)[7]
  • 【1004. 最大连续 1 的个数 III】滑动窗口(Python3)[8]
  • 【1234. 替换子串得到平衡字符串】[Java/C++/Python] Sliding Window[9]
  • 【1248. 统计「优美子数组」】滑动窗口(Python)[10]

扩展阅读

  • LeetCode Sliding Window Series Discussion

参考资料

[1]

【Python,JavaScript】滑动窗口(3. 无重复字符的最长子串): https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/pythonjavascript-hua-dong-chuang-kou-3-wu-zhong-fu/

[2]

76. 最小覆盖子串: https://leetcode-cn.com/problems/minimum-window-substring/solution/python-hua-dong-chuang-kou-76-zui-xiao-fu-gai-zi-c/

[3]

209. 长度最小的子数组: https://leetcode-cn.com/problems/minimum-size-subarray-sum/solution/209-chang-du-zui-xiao-de-zi-shu-zu-hua-dong-chua-2/

[4]

【Python】滑动窗口(438. 找到字符串中所有字母异位词): https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/solution/python-hua-dong-chuang-kou-438-zhao-dao-zi-fu-chua/

[5]

【904. 水果成篮】(Python3): https://leetcode-cn.com/problems/fruit-into-baskets/solution/904-shui-guo-cheng-lan-python3-by-fe-lucifer/

[6]

【930. 和相同的二元子数组】(Java,Python): https://leetcode-cn.com/problems/binary-subarrays-with-sum/solution/930-he-xiang-tong-de-er-yuan-zi-shu-zu-javapython-/

[7]

【992. K 个不同整数的子数组】滑动窗口(Python): https://leetcode-cn.com/problems/subarrays-with-k-different-integers/solution/992-k-ge-bu-tong-zheng-shu-de-zi-shu-zu-hua-dong-c/

[8]

【1004. 最大连续 1 的个数 III】滑动窗口(Python3): https://leetcode-cn.com/problems/max-consecutive-ones-iii/solution/1004-zui-da-lian-xu-1de-ge-shu-iii-hua-dong-chuang/

[9]

【1234. 替换子串得到平衡字符串】[Java/C++/Python] Sliding Window: https://leetcode.com/problems/replace-the-substring-for-balanced-string/discuss/408978/javacpython-sliding-window/367697

[10]

【1248. 统计「优美子数组」】滑动窗口(Python): https://leetcode-cn.com/problems/count-number-of-nice-subarrays/solution/1248-tong-ji-you-mei-zi-shu-zu-hua-dong-chuang-kou/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 脑洞前端 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 常见套路
    • 固定窗口大小
      • 可变窗口大小
      • 模板代码
      • 题目列表
      • 扩展阅读
        • 参考资料
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档