leetcode 76 最小覆蓋子串

2021-10-08 18:22:12 字數 2144 閱讀 7786

困難

給你乙個字串 s、乙個字串 t,請在字串 s 裡面找出:包含 t 所有字母的最小子串。

示例

輸入: s = "adobecodebanc", t = "abc"

輸出: "banc"

說明

如果 s 中不存這樣的子串,則返回空字串 「」。

如果 s 中存在這樣的子串,我們保證它是唯一的答案。

採用類似滑動視窗的想法

首先定義乙個字典,用來儲存t中的字元及對應個數

例如t=『abc』, t_dict=

在s中定義乙個滑動視窗,左右指標為left和right

定義最小的子串視窗,左右指標為min_left和min_right

當s的滑動視窗**現了t中的字元時,t_dict中對應value減一

當t_dict中所有value不大於0時,說明t的字元全部出現在視窗中

value可以為負,說明在視窗**現某字元的次數超過了t中的該字元的次數

為了判斷t中字元是否已經全部出現,定義t_len

視窗滑動**現了乙個字元,並且在t_dict中的value大於0時,t_len減1

當t_len等於0時,說明t的字元全部出現在視窗中

遍歷s時

from collections import defaultdict

class

solution

:def

minwindow

(self, s:

str, t:

str)

->

str:

t_dict = defaultdict(

int)

for char in t:

t_dict[char]+=1

t_len =

len(t)

left =

0 min_left =

0 min_right =

len(s)

for right, char in

enumerate

(s):

# 這樣寫的話每次視窗右端right自動右移

if char in t_dict and t_dict[char]

>0:

t_len -=

1if char in t_dict:

t_dict[char]-=1

# 視窗中已包含所有字元,需要移動left找到最短視窗

if t_len ==0:

while

true

:if s[left]

notin t_dict:

# 跳過非t中的字元

left +=

1elif t_dict[s[left]

]<0:

# 跳過比t出現中更多次的多餘字元

t_dict[s[left]]+=

1 left +=

1else

:break

# 最小視窗

if right - left < min_right - min_left:

min_left, min_right = left, right

# 最小視窗的第乙個字元肯定是t中的字元,left向後滑動

t_dict[s[left]]+=

1 t_len +=

1 left +=

1# 如果min_right沒有發生變化,說明沒有最小視窗,也就是無解

return

''if min_right ==

len(s)

else s[min_left:min_right +1]

if __name__ ==

"__main__"

: s =

"adobecodebanc"

t ="abc"

print

(solution(

).minwindow(s, t)

)

LeetCode76 最小覆蓋子串

給定乙個字串 s 和乙個字串 t,請在 s 中找出包含 t 所有字母的最小子串。示例 輸入 s adobecodebanc t abc 輸出 banc 說明 字串和雜湊表的問題。hashmap來儲存t字串中個字母元素的出現次數,left right記錄當前子字串的左右下標值,min minleft ...

leetcode 76 最小覆蓋子串

這道題我使用了很笨的方式花了好久解決了,但是時間複雜度太度,只看網上檢視原始碼,不得不說網上的答案基本都是一樣的,但是對於基礎相對薄弱的我來說這些 看起來很是費勁,還用要加強c 基礎的練習才行。思路相對來說不是很難 1 首先構架t字串的hash表,因為字元與ascii碼較好的關係,使用vector陣...

leetcode76 最小覆蓋子串

給定乙個字串 s 和乙個字串 t,請在 s 中找出包含 t 所有字母的最小子串。示例 輸入 s adobecodebanc t abc 輸出 banc 說明 如果 s 中不存這樣的子串,則返回空字串 如果 s 中存在這樣的子串,我們保證它是唯一的答案。典型雙指標滑動串列埠題目,先將t建dict,然後...