【算法】滑動窗口

滑動窗口

1.概念

滑動窗口是一類很常見的題型,最多見的就是子串問題,由於滑動窗口是一個連續的,因此很容易就是問知足條件的最大或者最小子串啊,這個條件就是不一樣的地方,但萬變不離其宗,滑動窗口就是一個窗口的移動。html

總之:子串+最值 --> 滑動窗口數組

滑動窗口有兩大類指針

  • 固定長度的滑動窗口:窗口的大小是固定好的,這是其實分爲了窗口造成和人窗口滑動兩個過程,窗口造成就是要先讓窗口達到要求的長度; 窗口滑動的過程在右邊界長的時候,左邊界也要跟着長,維持窗口長度不變;
  • 可變長度的滑動窗口:這也是遇到最多的,控制窗口移動的緣由不是長度,而是是否達到題目中某一條件,若是達到此條件,那右邊界停下,左邊界開始移動,試圖去破壞這一條件,就是在這個過程當中不斷的更新結果。

2.過程

  • 1.從題目中先整理出條件,常見的好比說子序列的和大於某值,子串中包含某些值,子串中出現了重複值,先把這些條件找出來,這就是用來移動窗口的依據;
  • 2.初始化left和right指針都爲0,right指針從頭走到尾,當不知足上面的條件時,right走,一直走到這個窗口知足上面咱們總結出來的條件了,停下;
  • 3.記錄下咱們要的答案,好比最典型的問子串的最小長度啊啥的,記錄下這時候咱們的right-left+1,這就是目前窗口的大小;
  • 4.右邊走不動了那左邊就得開始走了,移動左指針,每次移動都要把左指針的值給去除,由於咱們統計的結果只能是窗口裏的結果,出去了天然就不要了,而後,每一次左指針的移動都要判斷是否知足條件,好比要求子串和大於某一值,左邊移動一步,減去這個值看還大於目標值嗎,若是知足,更新咱們最終要的最小子串,由於這時候子串長度確定縮小了嘛,直到不知足條件爲止;若是不知足,那左指針不用再動了,右指針能夠開始動了,尋找下一個知足條件時停下來。
  • 5.就這樣重複,右邊動完左邊動,左邊動完右邊再動;

總結:右邊界要使窗口達到某一條件,左邊界使窗口跳出這一條件code

3.模板

int left = 0, right = 0;
while(right < nums.length){
    result = result + nums[right]; 
    //更新窗口內數據;
    //將移入窗口的值添加進結果,這裏就是不一樣題目不一樣要求;好比和,好比哈希表等;   
    while(判斷是否達到條件){  //若是達到條件左窗口就要收縮了;
        res = Math.min(res, right-left+1); //只要知足條件每次都要更新答案;
        //更新窗口內數據;
        result = result - nums[left]; //左窗口的值從結果去除;
        left++; //左窗口移動;
    }
    right++;  //只要不知足條件右窗口移動;
}

其實,咱們的右邊界就是在努力知足條件,找到一個可行解,而咱們的左邊界呢,想讓這個可行解更好一點,好比長度更短一下,是在尋找一個更好的最優解,可是極可能玩脫了不知足條件。htm

在套模板的時候咱們須要思考如下問題:blog

  • 1.當移動right,即加入結果的時候,須要更新哪些數據;
  • 2.到達什麼條件時,窗口中止擴大,也就是右邊界停下來,開始左邊界移動,縮小窗口;
  • 3.當移動left,即移出結果的時候,須要更新哪些數據;
  • 4.要的最後答案應該在窗口擴大仍是窗口縮小時更新;

4.樣例

3. 無重複字符的最長子串隊列

209. 長度最小的子數組get

劍指 Offer 59 - I. 滑動窗口的最大值模板

424. 替換後的最長重複字符統計

5.體會

  • 要可以根據題目要求找到條件,由於條件是指揮咱們移動左窗口仍是右窗口的長官,不知足條件,右窗口移動; 知足條件,左窗口移動;
  • 要始終清楚左右兩個邊界都是不會回退的,都是朝着最後走的,不可能會出現往回走的時候;
  • 兩個窗口不會同時移動,每次只有兩個窗口中的一個移動。
  • 換種思路:咱們的窗口滑動其實就是一個雙端隊列。當不知足條件時,數組元素依次從隊尾入隊;當知足條件時,隊首元素出隊;因此有的時候去想象成一個隊列,可能會更好的理解;
相關文章
相關標籤/搜索