每天两道LeetCodeHard:(12)

186 阅读2分钟

76. Minimum Window Substring

经典滑窗问题

题干:

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

解释:

找到最小的窗口,使得窗口内的字符数量等于目标字符串 两个关键点: 1,数量而非种类 2,On

思考:

经典的滑窗题目,没什么好想的,直接动态滑窗就行了。注意是要出现次数都和T中一致,所以先把右边界延伸,直到包含所有T为止,然后移动左边界,直到无法再移动为止,保持这个长度整体移动,总是尝试去移动左边界,直到右边界到末尾且左边界无法移动。整体时间复杂度On(每个元素被遍历2次或者3次)时间效率58%

答案:

class Solution(object):
    def minWindow(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: str
        """
        left,right=0,0
        tDict =defaultdict(int)
        wDict =defaultdict(int)
        res=[-1,-1]
        for i in t:
            tDict[i]+=1
        #stage 1: only right
        while right<len(s):
            rightA=s[right]
            if rightA in tDict:
                wDict[rightA]+=1
                if self.check(tDict,wDict):
                    break
            right+=1
        if right==len(s):
            return ""
        #stage 2:only left
        while left<right:
            leftA=s[left]
            if leftA in tDict:
                if wDict[leftA]-1<tDict[leftA]:
                    break
                wDict[leftA]-=1
            left+=1
        res[0],res[1]=left,right
        #stage 3:move together
        while right<len(s)-1:
            wDict[s[left]]-=1
            left+=1
            right+=1
            wDict[s[right]]+=1
            leftA=s[left]
            rightA=s[right]
            if self.check(tDict,wDict):
                while left<right:
                    if s[left] in tDict:
                        if wDict[s[left]]-1<tDict[s[left]]:
                            break
                        wDict[s[left]]-=1
                    left+=1
                if right-left < res[1]-res[0]:
                    res[1],res[0]=right,left
        if left==-1:
            return ""
        return s[res[0]:res[1]+1]

答案补充:

代码复杂度肯定是可以优化的,懒得想了,就直接想到哪写到哪了。感觉时间是输在如何判断是否覆盖了,这个的确是没想到好的解决办法。