给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。
一刷:
class Solution:
def minWindow(self, s: str, t: str) -> str:
tmap = collections.defaultdict(int)
for i in t:
tmap[i] += 1
left = 0
right = 0
minW = ""
slen = len(s)
tlen = len(t)
def check():
for i in tmap:
if tmap[i] >= 1:
return False
return True
# 第一个left:
for i in range(slen):
if s[i] in tmap:
left = i
right = left + tlen
break
if right == 0 or right > slen:
return minW
# 初始窗口
for i in range(left, right):
if s[i] in tmap:
tmap[s[i]] -= 1
flag = check()
# 进行滑动
while(right <= slen):
while(check()):
current = s[left: right]
if right-left == tlen:
return current
if minW == "":
minW = current
minW = minW if len(minW) <= len(s[left: right]) else s[left: right]
if s[left] in tmap:
tmap[s[left]] += 1
left += 1
else:
while(s[left] not in tmap):
left += 1
while(check() == False):
right += 1
if right > slen:
return minW
while(s[right-1] not in tmap):
right += 1
if right > slen:
return minW
tmap[s[right-1]] -= 1
return minW
二刷:用一个常数变量省略每次滑动i需要进行的check操作。
class Solution:
def minWindow(self, s: str, t: str) -> str:
i = j = 0
need = collections.defaultdict(int)
for c in t:
need[c] += 1
needCount = len(t)
res = (0, float('inf'))
for j, c in enumerate(s):
if c in need:
if need[c] > 0:
needCount -= 1
need[c] -= 1
if needCount == 0:
while True:
if s[i] in need:
if need[s[i]] == 0:
break
need[s[i]] += 1
i += 1
if j - i < res[1] - res[0]:
res = (i, j)
need[s[i]] += 1
needCount += 1
i += 1
return "" if res[1] > len(s) else s[res[0]:res[1] + 1]