第一章 核心套路篇 之 滑動視窗演算法框架

2021-10-17 11:10:02 字數 1896 閱讀 1152

滑動視窗演算法的主要**框架如下

// s 是所給的字串或者其他陣列

// t 是目標值

func

slidingwindow

(s, t string

) left, right :=0,

0 valid :=

0// s不一定是字串,還可以是其他型別的陣列

// 如果右指標還沒有到達s的終點

for right <

len(s)

}}

下面以例子來進行講解

leetcode 76題

如果我們使用暴力解法,偽**如下

for i:=

0;i<

len(s)

;i++

}}

但是上述的這個演算法時間複雜度比較高,如果採用滑動視窗進行解題,時間複雜度會大大降低

滑動視窗的思路如下:

在字串s中使用左右指標,初始化left=right=0,把索引左閉右開區間[left, right)稱為乙個視窗

不斷增加right指標擴大視窗[left, right),直到視窗中的字串符合要求(包含了t中的所有字元)

停止增加right,增加left不斷縮小視窗,更新資料,直到視窗中的字串不再符合要求

重複第2,3步,直到right到達字串的盡頭

上面思路中,其實第2步在尋找可行解,而第3步中不斷優化解,最終找到最優解,也就是最小覆蓋子串

needs用來標記t中字元出現次數,也就是我們需要的次數,window標記視窗中相應字元已經出現的個數。

同時要注意left和right所構成的區間是左閉右開的,所以初始條件下視窗中沒有任何元素。

valid變數表示視窗中滿足條件的字元個數,如果valid和需要的字元種類數相同,則說明視窗已經滿足條件,已經完全覆蓋目標串

func

minwindow

(s string

, t string

)string

for right <

len(s)

}// 向右移動一位之後滿足題目所給的條件

for valid ==

len(needs)

d := s[left]

left++if_

, ok := needs[d]

; ok

windows[d]--}

}}if length == max

else

}

leetcode

一種最簡單的方法就是將t的排列全部窮舉出來,然後去s中尋找,但是這個時間複雜度很高,全排列就需要n!的複雜度,不可取。

這道題目也可以使用滑動視窗進行求解,按照滑動視窗演算法框架,我們可以明確當視窗中的字串包含t中的所有字串時,我們需要對視窗進行壓縮

**在上個題目上進行改寫即可

func

checkinclusion

(s1 string

, s2 string

)bool

for right <

len(s2)

}// 向右移動一位之後滿足題目所給的條件

for right - left >=

len(s1)

d := s2[left]

left++if_

, ok := needs[d]

; ok

windows[d]--}

}}return

false

}

當然還有其他的題目,比如leetcode 438題, leetcode 劍指offer48題等題目都可以按照滑動視窗進行求解

滑動視窗演算法適合解決最小子串問題,這個演算法最主要的是要明確:

第一章 核心套路篇 之 BFS演算法套路框架

bfs breath first search 和dfs depth first search 是兩種十分常用的演算法,其中dfs演算法可以認為是回溯演算法 bfs演算法和核心就是將問題抽象成圖,從一點開始進行擴散,一般來說寫bfs的時候均使用佇列,每次將乙個結點周圍的所有結點加入到佇列中 bfs相...

第一章魔獸視窗

開始顯示第乙個窗體 使用者直接點登陸的話就會提示使用者名稱不能為空密碼不能為空 沒有賬號的話只能先註冊,點選藍色摁鈕進入下乙個窗體 這裡有判斷是否為空,註冊成功後利用窗體傳值,並且開啟第乙個視窗 把註冊的使用者名稱和密碼寫上去就可以的登陸到這個了 視窗一 1 usingsystem 2 usings...

第一章魔獸視窗

開始顯示第乙個窗體 使用者直接點登陸的話就會提示使用者名稱不能為空密碼不能為空 沒有賬號的話只能先註冊,點選藍色摁鈕進入下乙個窗體 這裡有判斷是否為空,註冊成功後利用窗體傳值,並且開啟第乙個視窗 把註冊的使用者名稱和密碼寫上去就可以的登陸到這個了 視窗一 1 using system 2using ...