leetcode 滑動視窗 程式設計

2021-10-07 13:38:58 字數 4897 閱讀 9551

演算法整理

滑動視窗思路,以下思路源自於此鏈結。

演算法技巧的思路非常簡單,就是維護乙個視窗,不斷滑動,然後更新答案麼。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...