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]  

 

posted @ 2020-06-12 10:56  nil_f  阅读(183)  评论(0)    收藏  举报