題目
給你一個字符串 S、一個字符串 T,請在字符串 S 裏面找出:包含 T 所有字符的最小子串。
示例:
輸入: S = “ADOBECODEBANC”, T = “ABC”
輸出: “BANC”
說明:
如果 S 中不存這樣的子串,則返回空字符串 “”。
如果 S 中存在這樣的子串,我們保證它是唯一的答案。
思路
雙指針滑窗法。 左右指針最開始都在0, 右指針遍歷元素。每一次迭代都判斷左右指針之間的字符是否已經包含了S中的字符,且數量是大於等於的。
碰到字符串,而且短時間無法想到解決辦法,那就想盡辦法用哈希。對於這道題,用兩個哈希表。其中一個存T的字符以及對應的數目;另一個字符串存滑窗內部的且屬於T中的字符串以及數目。
如果滑窗內部已經滿足了條件,就看看長度是不是最小的。然後左指針向前,繼續判斷是不是滿足條件。如果還滿足,左指針繼續向前;直到不滿足,才移動右指針。所以for循環內部有個while循環。
class Solution:
def minWindow(self, s: str, t: str) -> str:
ori = {}
cnt = {}
for a in t:
temp = ori.get(a, 0)
ori[a] = temp + 1
left = 0; right = float('inf')
ans_left = 0
n = len(s)
for i in range(n):
if s[i] in ori:
temp = cnt.get(s[i], 0)
cnt[s[i]] = temp + 1
while self.check(ori, cnt) and left <= i: # 滑窗內滿足條件
if i - left + 1 < right - ans_left+1: # 更新最小串位置
right = i
ans_left = left
if s[left] in ori: # 左指針前移,對應的數量發生減一。
cnt[s[left]] -= 1
left += 1
if right == float('inf'):
return ""
return s[ans_left:right+1]
def check(self, ori, cnt):
for k,v in ori.items():
if not cnt.get(k, None):
return False
if cnt[k] < v:
return False
return True