一文帶你AC十道題【滑動窗口】

2021-03-02 腦洞前端

你可以選擇點擊文章最下方的閱讀原文,去我的博客以獲得更好的閱讀體驗。


筆者最早接觸滑動窗口是滑動窗口協議,滑動窗口協議(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 操作效率!




相關焦點

  • 另一道滑動窗口算法題【最長無重複子串】
    一 前言        昨天寫了一個算法題,引出一個求解方法——滑動窗口。很多人只是掃了一眼,沒細看文中代碼,就很不以為意。
  • 【每日一題】643. 子數組最大平均數 I
    各位題友大家好,今天是每日算法題公眾號堅持日更的第 11 天。今天力扣上的每日一題是第 643 題「子數組最大平均數 I」。題目也可以抽象成長度固定為 k 的滑動窗口。需要注意的是,需要根據 i 的位置,計算滑動窗口是否開始、是否要移除最左邊元素:當 i >= k - 1 時,最左邊第一個滑動窗口內的元素剛好 k 個,開始計算滑動窗口的最大和。當 i >= k 時,為了固定窗口的元素是 k 個,每次移動時需要將 i - k 位置的元素移除。
  • [每日一題]3. Longest Substring Without Repeating Characters
    因為他的大學同學在同學群裡發了一道 Google 面試題,他想找老馬聊聊思路。老馬看了看王小二手中的題目,大概的意思是輸入一個純小寫英文字母組成的字符串,輸出該字符串的最長的沒有重複字母的子串的長度。老馬一直很滿意王小二的勤奮好學,所以還是非常樂意跟王小二分享算法方面的思路。老馬先問王小二自己的想法:「小二, 這道題你自己有什麼思路嗎?」
  • 滑動窗口也能用於實例分割,陳鑫磊、何愷明等人提出圖像分割新範式
    但相比之下,該領域的密集滑動窗口實例分割並未取得同步的進展。為什麼邊界框的密集檢測發展如此之快,但實例分割卻落後了呢?這是一個具有根本科學意義的問題。該論文的目標就是彌補這一差距並為密集實例分割研究奠定基礎,為了這個目標,作者提出了一種名為 TensorMask 的框架。
  • 一文搞懂 MySQL 的窗口函數
    窗口函數按照實現方式分成兩種:一種是非聚合窗口函數,另外一種是聚合窗口函數。非聚合窗口函數是相對於聚合窗口函數來說的。聚合函數是對一組數據計算後返回單個值(即分組),非聚合函數一次只會處理一行數據。窗口聚合函數在行記錄上計算某個欄位的結果時,可將窗口範圍內的數據輸入到聚合函數中,並不改變行數。
  • 春節大禮包|刷題技巧+80道Leetcode
    為了跳槽,我前兩年的春節都是在刷題中度過的,目前為止刷了小四百道leetcode,也算是有一些經驗,今天就跟大家分享下學習方法和我總結的乾貨。每個 book 裡都是先教學、再由易到難地實戰,一個知識點大概有十幾道題,刷完基本上就能掌握一些套路,到medium的水平了。然後才是去看各種面經和高頻題,給自己查漏補缺,並且要稍微記錄一下,幾行代碼或者解題思路,方便自己快速複習。下面就是我去年刷題時的筆記(文末下載):
  • 摩擦生熱中摩擦力為何必須是滑動摩擦力?高一物理
    學霸們課下都痴迷於刷題,題多做些對學好物理是非常有幫助的。刷題目的是什麼?這值得咱們去琢磨和反思。典型習題演練,一方面幫您進一步鞏固課堂所學考點,另一方面幫您梳理解題思路,鍛鍊分析能力。我的書物理自診斷最大特點是每道題都配有我的視頻解析,掃題旁二維碼即可查看我的視頻講解。這樣通過做題,就能快速診斷出自己的學習問題,如知識點是否有漏洞?公式使用錯誤?
  • 小升初數學易錯題精選100道,名師詳解,帶你向滿分衝刺!
    尤其是數學這門學科,做好小升初階段的準備,實在是百利而無一害。數學本來就是學生最為擔心的一門學科,它的學習在中小學佔據主要的位置,家長和學生都應該加以重視。小升初數學無非就那些知識點,只要掌握通透,就絕對沒有問題。小學數學知識點雖然不多,但是看起來卻十分雜亂,需要把重難點考點整理出來。小升初就是起著這樣一個作用,這個階段就是鞏固以前所學,解決曾經遺留的問題。
  • 「面試題解」算法題:如何快速求出所有子矩陣中元素的最大值?
    如果你給出的是這個答案,那麼你就和機智的水蜜桃同學一樣,給出了一個非常正確的解法。相信每個有編程基礎的同學完成這段編碼邏輯不會有任何問題的,不過這個算法的複雜度高達O((n-k+1)^2 * k^2)。雖然我們樸素的解法確實挺暴力的,但也能給我們一些啟發吧。
  • 帶壓開孔的機座與滑動軸承原理
    帶壓開孔設備的機座是帶壓開孔設備的基礎部件,機器的零部件安裝在機座上進行管道帶壓開孔作業。因此,帶壓開孔機座既要起到帶壓開孔刀及中心鑽以及鑽軸的支撐作用,承受這些零部件的重量,又要起到設備的基準作用,保證部件之間的相對位置。
  • 回溯法|一文解決四道 Leetcode「組合總和」題
    回溯法|一文解決四道 Leetcode「組合總和」題看完本篇文章,你可以解決下面四道」組合總和「的題目:這四道題都屬於Media難度的題目,但是基本都可以用同一套思想和方法解決。range(i, len(candidates)):                backtrack(j+1, temp_sum+candidates[j], temp_list+[candidates[j]])        backtrack(0,0,[])        return res我們發現在這一題中
  • 這道中考物理題得滿分者為零!看似熟悉?很多坑早就等著你跳了
    在研究錯題的過程中,你會重新審視當初的思維障礙點、關鍵點、錯因、規範思路和規範解題步驟,重新牢記各種有些陌生了的各種結論,甚至在研究各種錯題的過程中,會發現新的思路,產生創新性思維火花,會把同類型題無意中串聯起來,從而形成各種類型題的解題方案!這個過程是一個快速獲得成果的過程,是一個最有成就感、快速提升信心的過程!
  • 第二道初中物理競賽題幾乎全軍覆沒!過半初中生做錯第一道!
    一般情況下競賽題並不會超出中考物理大綱的範圍,可以肯定的是,總的來說,競賽題要比平時訓練的題目更綜合一些,更考察各種思維能力和創新能力,從而導致多數初中生感覺物理競賽題難。我們今天就來見識一下初中物理競賽題的真面目吧,這是兩道電學競賽題,從圖中可以看出這兩道題比中考物理電學題難,而且幾乎所有初中生會倒在第二道電學題上,超過半數學生會做錯第一道題。
  • 四道初三物理電學易錯題!最典型!期末必考其一!
    還沒有進行期末考試的初三學生們請認真研究一下,如果你完全做對並且覺得很簡單,那說明這塊內容學的還不錯,如果做錯了甚至不會做,那就需要在期末考試之前趕快鞏固一下了,因為這四道題不屬於難題,而是屬於比較常見的常規題型。
  • LeetCode刷題筆記 - 3. 無重複字符的最長子串
    學好算法很重要,然後要學好算法,大量的練習是必不可少的,LeetCode是我經常去的一個刷題網站,上面的題目非常詳細
  • 一文搞定 UDP 和 TCP 高頻面試題!
    ,再有面試官問你相關的知識點,看這篇就夠了!)6、TCP 長連接和短連接的區別7、TCP粘包、拆包及解決辦法8、TCP 可靠傳輸9、TCP 滑動窗口10、TCP 流量控制1、UDP 和 TCP 的特點與區別用戶數據報協議 UDP(User Datagram Protocol)是無連接的,盡最大可能交付,沒有擁塞控制,面向報文(對於應用程式傳下來的報文不合併也不拆分,只是添加 UDP 首部),支持一對一、一對多、多對一和多對多的交互通信。
  • 帶你學會必考實驗:探究滑動摩擦力大小的影響因素(專題複習3)
    【經典例題】例1 本題選自騰訊課堂付費課程《初中物理力學專題突破》-01力、相互作用力與平衡力-探究滑動摩擦力大小的影響因素(1)小明在「探究滑動摩擦力大小與接觸面粗糙程度、壓力大小的關係」實驗中,設計了如下表格,並記錄了如下實驗數據.為完成實驗探究,表格中至少還需要在(a)(b)
  • 電學經典題(一),第一教育大省的物理中考原題
    下面就這教育大省的2018年中考物理試題中的電學題,精選而出的4道題進行梳理分析。其中2道是電學故障問題,2道是電學綜合考查題。我們一起來看看。揚州市2018初中畢業升學考試物理試題第8題上圖是揚州市2018年初中畢業、升學統一考試物理試題第8題,也是考查電路故障題,難度比上一題小多了。
  • 高考數學最後一題,難住你了嗎?19道經典壓軸題帶你開拓解題思路
    北大學霸:手把手教你解析歷年高考大題思路高考理科數學壓軸題難度評分榜:本文評價一下各省的理科高考數學中比較難的題目並給出解答,並且給出我個人認為的難度評分(最低一星,最高五星)。· 難度評分是非常主觀的事情,難免帶有個人偏見,如果我覺得的難度評分和讀者的相差很大,請大家諒解;· 我個人覺得5分的題目難度可能相當於競賽難度,大於等於4.5分題目難度比考研數學一題目難度難的多,意思是原封不動放在考研數學裡嚴格難於現有考研最難的題目,對絕大部分同學即使大學或者因為考研學了一大堆數學,極限拉格朗日乘子泰勒公式等等一堆工具隨便用
  • 帶壓開孔機滑動軸承保養
    由於帶壓開孔在管道帶壓開孔施工作業中的特殊生產工藝要求,帶壓開孔機是在極為惡劣的作業環境和工況下進行。面對管道內介質的壓力、溫度等條件,還由於帶壓開孔設備的自重、開孔時切削環境溫度高,粉塵大以及管線內含酸性腐蝕氣體CO,SO2等,對設備的潤滑帶來很多問題,運轉時磨損嚴重。