LeetCode 76. 最小覆盖子串
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解析:使用滑动窗口,滑动窗口模板详见我的博客专栏算法进阶之滑动窗口
class Solution:
def minWindow(self, s: str, t: str) -> str:
from collections import defaultdict
need = defaultdict(int) # 记录需要的字母个数
window = defaultdict(int) # 当前窗口中的所需要的字母个数
if not s or not t: # 任何一个为空,就返回空
return ''
for i in t:
need[i] += 1 # 统计需要的每一个字母的个数
left = 0
right = 0
n = len(s)
valid = 0 # 个数满足need的字母个数
start = 0 # 结果字符串的开始索引
min_len = float('inf') # 结果字符串的长度
while right < n:
c = s[right]
right += 1
if c in need:
window[c] += 1
if need[c] == window[c]: # 字母c满足,valid + 1
valid += 1
while valid == len(need): # 全部满足need
if right - left < min_len: # 更新结果字符串的长度和开始索引
min_len = right - left
start = left
d = s[left] # 左边第一个字符
left += 1 # 缩紧窗口的左边界
if d in need: # 如果 d在need中,并且d的个数正好等于need的个数,那么缩紧之后,就会不满足,此时valid-1
if window[d] == need[d]:
valid -= 1
window[d] -= 1 #如果 d在need中,window中减少一个d
# 如果长度为Inf,也即不存在,返回空
return '' if min_len == float('inf') else s[start:start + min_len]