76. 最小覆盖子串

https://leetcode-cn.com/problems/minimum-window-substring/

解法一:滑动窗口

将t的字符存入字典map中,t中未出现而s中出现的词频设为0。这样的目的是t要求的字符词频为正数

(贪心法?)由于题目要求的只是‘包含’,用[begin…end]表示窗口,end先向前移动,用直方图法判断子串是否符合t。若符合,begin再向前压缩窗口。

class Solution:
    def minWindow(self, s: str, t: str) -> str:
		# 先统计词频,t中的字符词频大于0,在s中不在t中的等于0        
        map = dict()    
        for c in t:
            if c in map:
                map[c] += 1
            else:
                map[c] = 1
        for c in s:
            if c not in map:
                map[c] = 0

        count = 0  #表示匹配情况
        begin, end = 0, 0
        d = sys.maxsize  #记录窗口最小值
        head = 0  #记录最小窗口起始

        while end < len(s):
            if map[s[end]] > 0:  #只有遇到需要的字符(词频大于0的),count才计数
                count += 1
            map[s[end]] -= 1    #当前字符词频减1
            end += 1
            while count == len(t):  #若匹配,begin前移
                if end - begin < d:  #找到更小的窗口
                    d = end - begin
                    head = begin  
                if map[s[begin]] == 0:    #若移动处是需要的字符,修改count
                    count -= 1
                map[s[begin]] += 1
                begin += 1

        if d == sys.maxsize:    #若找不到
            return ""
        else:
            return s[head:head+d]

解法二:滑动窗口模板

方法一不适用于其他滑动窗口题,关键在于只用一个map无法准确描述匹配情况

import sys
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        need={}
        window = {}
        for c in t:
            need[c] = need.get(c, 0)+1
        left=0      #窗口左边界
        right=0     #窗口右边界
        start=0     #记录子串起点
        minLen = sys.maxsize    #最小长度
        valid=0      #t串与s串匹配次数
        while right <len(s):
            #增大窗口
            c=s[right]
            right+=1
            if c in need:   #该字符在t串中
                window[c] = window.get(c, 0)+1
                if window[c] == need[c]:    #该字符匹配
                    valid +=1
            while valid==len(need):
                #更新
                if right-left < minLen:
                    minLen = right -left
                    start=left
                #缩小窗口,与增大窗口的操作对称
                d = s[left]
                left += 1
                if d in need:
                    if window[d] == need[d]:
                        valid -=1
                    window[d] -= 1

        return "" if minLen==sys.maxsize else s[start:start+minLen]

最后更新于