含有所有字符的最短字符串(hard)
leetcode76题
简单实现,非最优解
class Solution:
def minWindow(self, s: str, t: str) -> str:
n1 = len(s)
n2 = len(t)
if n1 < n2: return ""
res = []
minL = n1+1
cnt = {}
cur = {}
for c in t:
if c in cnt:
cnt[c] += 1
else:
cnt[c] = 1
cur[c] = 0
count = 0 #记录已匹配数目
l = 0
while l < n1 and s[l] not in cnt: l+=1 #找到匹配起点
if l >= n1: return "" #找不到起点
r = l #窗口左右端点
while l < n1:
#右窗口滑动
while r < n1 and count < n2:
if s[r] not in cnt: #非目标字符
r += 1
continue
c = s[r]
cur[c] += 1 #记录每类目标字符个数
#目标字符数目满足则不计数
count += 1 if cur[c] <= cnt[c] else 0
r += 1
if count < n2: break #遍历完成,不存在可能的更优解则跳出循环
if minL > (r-l): #新的最优解
res = [l,r]
minL = r-l
#左窗口滑动,可能出现3种情况:
#1、s[l]是非目标字符,则舍弃s[l]所得解更优,当舍弃s[l]
#2、s[l]是多于要求的目标字符,也该舍弃,当前窗口存在更优解时最初的s[l]一定是这种情况
#3、s[l]是刚好符合要求的目标字符,则s[l,r]可能就是新的最优解,
#判断过后舍弃s[l],开始下一趟循环,已匹配字符减1
while l < n1:
if s[l] not in cnt: #情况1
l += 1
continue
c = s[l]
l += 1
cur[c] -= 1
if cur[c] < cnt[c]: #情况3
if minL > (r-l+1):
res = [l-1,r]
minL = r-l+1
count -= 1
break
if not res: return ""
return s[res[0]:res[1]]
```