題目:
給定一個字符串 S 和一個字符串 T,請在 S 中找出包含 T 所有字母的最小子串。
示例:
輸入: S = "ADOBECODEBANC", T = "ABC"
輸出: "BANC"
輸出: "BANC"
說明:
如果 S 中不存這樣的子串,則返回空字符串 ""。
如果 S 中存在這樣的子串,我們保證它是唯一的答案。
如果 S 中存在這樣的子串,我們保證它是唯一的答案。
解題思路:
class Solution: def minWindow(self, s, t): res = "" if len(s) < len(t): return res left = 0 right = 0 min_len = len(s) + 1 m = {} count = 0 for i in t: m[i] = m.get(i,0) + 1#統計t中字符數目 while right < len(s): if s[right] in m: m[s[right]] -= 1 if m[s[right]] >= 0: count += 1 while (count == len(t)): if (right - left + 1 < min_len): min_len = right-left+1 res = s[left:right+1] if s[left] in m: m[s[left]] += 1 if m[s[left]] > 0: count -= 1 left += 1 right += 1 return res

算法思路:總的來說,我們希望圈定一個最小的窗口,這個窗口里包含所有t中的字符,並且這個窗口的長度要最短。
所以,我們需要邊界指針left,right來去圈定我們窗口的范圍。
1.先遍歷t中字符串,找到各字符出現個次數,儲存在hash中。
2.再遍歷s中字符串,每遇到一個t中的字符,則把對應hash value - 1,如果這個字符對應的值大於等於0,則count++。這一段我們的目的是划定一個s中的區間,這個區間包含所有t中字符。count 表示t中有幾個字符在s中(當前窗口區間),不包括s中多的重復的字符。
3.當count 第一次等於 t.size()時,說明我們第一次圈定了一個區間,滿足所有t中字符在這個區間中都可以找到,但不能保證最短。於是我們更新最短長度,以及最短字符串。接下來我們要右移我們的窗口了,如果我們這個窗口的第一項(也就是要挪動,要移除的那一項)是組成t所需要的,那我們如果要移除掉它,則hash值要加一,因為我們當前窗口接下來不會包含那個字符了,同時count也要根據情況減少,因為count表示s窗口中能找到t的幾個字符,現在窗口右移,不包含那個必須組件了,於是要-1。