滑動視窗演算法的主要**框架如下
// 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 ...