leetcode 每日一题 76. 最小覆盖子串
滑动窗口
思路:
①从头开始,找到S中第一个包含t所有字符的子串,也即这个子串的最后一个字符必然是T中的某个字符。
②对找到的子串从头开始进行剪枝处理,将不必要的元素排除在外,即直到遇到第一个包含在T中的字符为止,记录滑动窗口最小值和位置。
③以滑动窗口第一个字符的下一位开始,继续①②操作
例如:
S : ADOBECODEBANC T : ABC
①首先从S找到包含T所有字符的子串ADOBEC,记录窗口位置0,5
②从D开始继续寻找包含T所有字符的子串DOBECODEBA
③去除窗口中多余的字符DO,剩余子串为BECODEBA,由于窗口大小8>6,所以不记录
④从E开始继续寻找包含T所有字符的子串ECODEBA
⑤去除窗口中多余的字符E,剩余子串为CODEBA,由于窗口大小6=6,所以不记录
⑥从O开始继续寻找包含T所有字符的子串ODEBANC
⑦去除窗口中多余的字符ODE,剩余子串为BANC,由于窗口大小4<6,所以更新窗口位置(9,12)
得到最终答案BANC
代码:
import collections class Solution: def minWindow(self, s: str, t: str) -> str: need=collections.defaultdict(int) for c in t: need[c]+=1 needCnt=len(t) i=0 res=(0,float('inf')) for j,c in enumerate(s): if need[c]>0: needCnt-=1 need[c]-=1 if needCnt==0: while True: c=s[i] if need[c]==0: break need[c]+=1 i+=1 if j-i<res[1]-res[0]: res=(i,j) need[s[i]]+=1 needCnt+=1 i+=1 return '' if res[1]>len(s) else s[res[0]:res[1]+1]