演算法整理
滑動視窗思路,以下思路源自於此鏈結。
演算法技巧的思路非常簡單,就是維護乙個視窗,不斷滑動,然後更新答案麼。leetcode 上有起碼 10 道運用滑動視窗演算法的題目,難度都是中等和困難。該演算法的大致邏輯如下:
int left =
0, right =0;
while
(right < s.size())
}
這個演算法技巧的時間複雜度是 o(n),比字串暴力演算法要高效得多。
其實困擾大家的,不是演算法的思路,而是各種細節問題。比如說如何向視窗中新增新元素,如何縮小視窗,在視窗滑動的哪個階段更新結果。即便你明白了這些細節,也容易出 bug,找 bug 還不知道怎麼找,真的挺讓人心煩的。
所以今天我就寫一套滑動視窗演算法的**框架,我連再**做輸出 debug 都給你寫好了,以後遇到相關的問題,你就默寫出來如下框架然後改三個地方就行,還不會出 bug:
/
* 滑動視窗演算法框架 *
/void slidingwindow(string s, string t)
}}
其中兩處 … 表示的更新視窗資料的地方,到時候你直接往裡面填就行了。
而且,這兩個 … 處的操作分別是右移和左移視窗更新操作,等會你會發現它們操作是完全對稱的。
規律總結
新增鏈結描述
# 執行效率更高
class
solution
:def
maxsubarray
(self, nums: list[
int])-
>
int:
for i in
range(1
,len
(nums)):
nums[i]
+=max
(nums[i-1]
,0)return
max(nums)
class
solution
:def
maxsubarray
(self, nums: list[
int])-
>
int:
dp=[nums[0]
]for i in
range(1
,len
(nums)):
max(nums[i]
,dp[i-1]
+nums[i]))
return
max(dp)
新增鏈結描述
題目總結
class
solution
:def
lengthoflongestsubstring
(self, s:
str)
->
int:
ifnot s:
return
0 left=
0 lookup=
set(
) n=
len(s)
max_len,cur_len=0,
0for i in
range
(n):
cur_len+=
1while s[i]
in lookup:
lookup.remove(s[left]
) left+=
1 cur_len-=
1if cur_len>max_len:max_len=cur_len
lookup.add(s[i]
)return max_len
題解
class
solution
:def
lengthoflongestsubstring
(self, s:
str)
->
int:
from collections import defaultdict
lookup=defaultdict(
int)
start,end,max_len,counter=0,
0,0,
0while end<
len(s)
:if lookup[s[end]
]>0:
counter+=
1 lookup[s[end]]+=
1 end+=
1while counter>0:
if lookup[s[start]
]>1:
counter-=
1 lookup[s[start]]-=
1 start+=
1 max_len=
max(max_len,end-start)
return max_len
題目鏈結
class
solution
:def
minsubarraylen
(self, s:
int, nums: list[
int])-
>
int:
ifnot nums:
return
0 n =
len(nums)
ans = n +
1for i in
range
(n):
total =
0for j in
range
(i, n)
: total += nums[j]
if total >= s:
ans =
min(ans, j - i +1)
break
return
0if ans==n+
1else ans
# 模板法
class
solution
:def
minsubarraylen
(self, s:
int, nums: list[
int])-
>
int:
ifnot nums:
return
0 n=
len(nums)
total=
0 min_len=
float
('inf'
) start,end=0,
0while endtotal+=nums[end]
end+=
1while total>=s:
min_len=
min(min_len,end-start)
total-=nums[start]
start+=
1return
0if min_len==
float
('inf'
)else min_len
新增鏈結描述
題解defaultdict函式
class
solution
:def
minwindow
(self, s:
str, t:
str)
->
str:
from collections import defaultdict
lookup = defaultdict(
int)
for c in t:
lookup[c]+=1
start =
0 end =
0 min_len =
float
("inf"
) counter =
len(t)
res =
""while end <
len(s)
:if lookup[s[end]
]>0:
counter -=
1 lookup[s[end]]-=
1 end +=
1while counter ==0:
if min_len > end - start:
min_len = end - start
res = s[start:end]
if lookup[s[start]]==
0:counter +=
1 lookup[s[start]]+=
1 start +=
1return res
題目
題解
# 會超出時間限制 其中一種簡單的方法
class
solution
:def
maxslidingwindow
(self, nums: list[
int]
, k:
int)
-> list[
int]
: n =
len(nums)
if n * k ==0:
return
return
[max
(nums[i:i + k]
)for i in
range
(n - k +1)
]
題目 滑動視窗leetcode
給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗 k 內的數字。滑動視窗每次只向右移動一位。返回滑動視窗最大值。示例 輸入 nums 1,3,1,3,5,3,6,7 和 k 3輸出 3,3,5,5,6,7 解釋 滑動視窗的位置 最大值 1 ...
leetcode 滑動視窗
面試題57 ii.和為s的連續正數序列 題目 輸入乙個正整數 target 輸出所有和為 target 的連續正整數序列 至少含有兩個數 序列內的數字由小到大排列,不同序列按照首個數字從小到大排列。題解 摘自 什麼是滑動視窗 滑動視窗可以看成陣列中框起來的乙個部分。在一些陣列類題目中,我們可以用滑動...
leetcode 滑動視窗
3.無重複字元的最長子串 給定乙個字串,請你找出其中不含有重複字元的最長子串的長度。示例 1 輸入 abcabcbb 輸出 3解釋 因為無重複字元的最長子串是 abc 所以其長度為 3。示例 2 輸入 bbbbb 輸出 1解釋 因為無重複字元的最長子串是 b 所以其長度為 1。示例 3 輸入 pww...