LeetCode習題總結 演算法(15)

2021-10-06 16:46:53 字數 3277 閱讀 1389

首先先上原題:

在剛看到這道題的時候,也許對於題目的意思能夠進行很好的理解。即本題想要實現的是給定一字串,尋找出最大的無重複子串。但是,我們在面對題目所給樣例如abcabcbb或是pwwekw這樣的包含重複子串的整串時,如果能夠將重複的子串進行適當的刪除操作。這便是本題中最為核心的部分。那麼如果我們需要尋找到乙個最大的無重複子串,首先我們需要做便是遍歷操作,遍歷操作可以用for語句來進行實現。此時,針對是否重複這個問題,我們便可以利用in方法來實現對重複元素的判定操作。如果所遍歷的元素存在於對應的列表中,我們可以將字串最左邊的下標向右移動一位,實現了對重複元素的特定刪除操作;反之如果不在,則我們也可以進行類似的操作,即最右邊的下標向右移動一位,實現了對最大無重複子串的更新操作;同時更新最大無重複子串長度的更新操作,即完成了對當前子串是所需尋找的目標。而這一更新刪除操作,我們可以通過設定兩個相應左右(雙)指標來完成對應的檢索操作,這便是針對本題最為廣為流行的一種方法:利用**雙指標(滑動視窗)**來實現對字串中最大公共子串的查詢方法。基本該思想,本文給出方法1和方法2的兩種形式的雙指標(滑動視窗)演算法**。

class

solution

:def

lengthoflongestsubstring

(self, s:

str)

->

int:

length = left = right =

0while right <

len(s)

:# 利用列表的切片方法判斷對應的字元是否在當前最大非重複子串內:

# 1、如果不在,則右指標向右移動一位,同時完成對當前最大非重複子串長度的更新

if s[right]

notin s[left:right]

: right +=

1 length =

max(length , right - left)

# 2、如果在的話,則左指標向右移動一位,完成對應的刪除操作。

else

: left +=

1return length

該演算法在執行器裡面執行消耗時間和消耗記憶體空間如下圖所示:

class

solution

:def

lengthoflongestsubstring

(self, s:

str)

->

int:

occ =

set(

) n =

len(s)

# 設定移動指標和最大無重複字串長度

rlink , length =-1

,0for i in

range

(n):

# 只有檢測到出現重複公共子串時,才會進入此操作,刪除對應的字元

if i !=0:

occ.remove(s[i]

)# 當遍歷到的字元不存在於滑動視窗,那麼就將對應檢索的字元加到滑動視窗當中

while rlink +

1< n and s[rlink +1]

notin occ:

occ.add(s[rlink +1]

) rlink +=

1 length =

max(length , rlink - i +1)

return length

該演算法在執行器裡面執行消耗時間和消耗記憶體空間如下圖所示:

class

solution

:def

lengthoflongestsubstring

(self, s:

str)

->

int:

# 字串為空則返回零

ifnot s:

return

0 max_length ,left, right =

0# 滑動視窗陣列

for i, c in

enumerate

(s):

# 如果字元不在滑動視窗中,則直接擴充套件視窗

if c not

in s[left:right]

:# 右指標右移一位

right +=

1# 如果字元在滑動視窗中,則

# 1、 從視窗中移除重複字元及之前的字串部分

# 2、 再擴充套件視窗

else

:# 在滑動視窗範圍內中找出對應的首個字元的索引x,對應的新的左指標位置為x + 1

# 左指標右移 索引x增一位

left += s[left:right]

.index(c)+1

# 擴充套件視窗大小

right +=

1# 更新最大長度

max_length =

max(right - left, max_length)

# 返回最大無重複子串有兩種長度:

# 1、如果最大長度不為零,返回最大長度

# 2、如果最大長度仍為零,則說明遍歷整個字串都沒有發現重複字元,最大長度即為字串本身的長度

return max_length if max_length !=

0else

len(s)

該演算法在執行器裡面執行消耗時間和消耗記憶體空間如下圖所示:通過此題可以看出,在面對各式各樣演算法問題的時候,我們更多的應該學會的是將該問題化解成求解n個子問題的步驟。以此來簡化求解問題的每個步驟。並加以考量可能存在的邊界條件;逐步將每乙個步驟轉化成對應的程式語言所能表達的小模組,然後將每個功能進行拼接。這便能完成對演算法的求解過程。所以說,演算法難,不在於我們所面對的問題是否無比複雜,而更多的在於,我們是否能將乙個整的大問題逐步的分解成每個小問題。這便是演算法的微妙核心所在。

LeetCode習題總結 演算法(5)

首先先上原題 通過給定對應七種羅馬數字對應的七種字元 i,v,x,l,c,d 和 m 以及對應七種字元所對應的數值 i 1,v 5,x 10,l 50,c 100,d 500,m 1000。去求解在給定乙個羅馬字串時,對應的羅馬數字表示為多少。思路 基於此題目,我們可以發現對應的羅馬字元和羅馬數字之...

LeetCode習題總結 演算法(10)

首先先上原題 拿到這道題,我們採取以下的思想來處理這個問題 1 是否特定的子串在正串中存在?2 如果不存在,我們應該返回什麼樣的數值?3 如果存在,我們該怎樣找尋子串在正串中第一次出現的位置?當我們拿到這道題時,如果能把以下幾道題能夠思考明白,想必這道題的難度係數也不會太大。那我們以此來思考上述的幾...

六一兒童節之LeetCode習題總結 演算法(14)

首先先上原題 背景闡述 輸入 candies 2,3,5,1,3 extracandies 3 輸出 true,true,true,false,true 解釋 孩子 1 有 2 個糖果,如果他得到所有額外的糖果 3個 那麼他總共有 5 個糖果,他將成為擁有最多糖果的孩子。孩子 2 有 3 個糖果,如...