你可以選擇點擊文章最下方的閱讀原文,去我的博客以獲得更好的閱讀體驗。
筆者最早接觸滑動窗口是滑動窗口協議,滑動窗口協議(Sliding Window Protocol),屬於 TCP 協議的一種應用,用於網絡數據傳輸時的流量控制,以避免擁塞的發生。發送方和接收方分別有一個窗口大小 w1 和 w2。窗口大小可能會根據網絡流量的變化而有所不同,但是在更簡單的實現中它們是固定的。窗口大小必須大於零才能進行任何操作。
我們算法中的滑動窗口也是類似,只不過包括的情況更加廣泛。實際上上面的滑動窗口在某一個時刻就是固定窗口大小的滑動窗口,隨著網絡流量等因素改變窗口大小也會隨著改變。接下來我們講下算法中的滑動窗口。
介紹滑動窗口是一種解決問題的思路和方法,通常用來解決一些連續問題。比如 LeetCode 的 209. 長度最小的子數組。更多滑動窗口題目見下方題目列表。
常見套路滑動窗口主要用來處理連續問題。比如題目求解「連續子串 xxxx」,「連續子數組 xxxx」,就應該可以想到滑動窗口。能不能解決另說,但是這種敏感性還是要有的。
從類型上說主要有:
窗口大小不固定,求解最小的滿足條件的窗口(上面的 209 題就屬於這種)後面兩種我們統稱為可變窗口。當然不管是哪種類型基本的思路都是一樣的,不一樣的僅僅是代碼細節。
固定窗口大小對於固定窗口,我們只需要固定初始化左右指針 l 和 r,分別表示的窗口的左右頂點,並且保證:
初始化 r,使得 r - l + 1 等於窗口大小4.1 如果滿足,再判斷是否需要更新最優解,如果需要則更新最優解可變窗口大小對於可變窗口,我們同樣固定初始化左右指針 l 和 r,分別表示的窗口的左右頂點。後面有所不同,我們需要保證:
4.1 如果滿足,再判斷是否需要更新最優解,如果需要則更新最優解。並嘗試通過移動 l 指針縮小窗口大小。循環執行 4.1形象地來看的話,就是 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]【Python】滑動窗口(438. 找到字符串中所有字母異位詞)[4]【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/
推薦閱讀
1、【每日算法Day 70】圖解算法:小學生都會的數塊數問題,你會嗎?
2、超詳細!從本質上搞懂困惑你多年的KMP匹配算法
3、十大經典排序算法整理匯總(附代碼)
4、外部排序:如何用 2GB內存給 20 億個整數排序?
5、【每日算法Day 67】經典面試題:手動開根號,你知道幾種方法?
6、用好這幾個工具,能大幅提升你的 Git/GitHub 操作效率!