题目
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
class Solution:
def minWindow(self, s: str, t: str) -> str:
if len(t) > len(s):
return ""
t_counter = collections.Counter(t)
i_j_counter = collections.Counter()
res = ""
# 双指针
i, j = 0, 0
while j < len(s):
i_j_counter += collections.Counter(s[j])
j += 1
while not t_counter - i_j_counter:
if j - i == len(t): # s中包含子串 t
return s[i:j]
if not res or j - i < len(res):
res = s[i:j]
i_j_counter -= collections.Counter(s[i])
i += 1
return res
- 关键部分在于如何快速比较一个字符串是另一个字符串的子串;
- 需要在遍历字符串的同时保存 window 内的字符串,同时高效判断该 window 内字符串是否包含字符串 t 中的所有字符;
- 此处使用 python 内置的
collections.Counter
方案二(leetcode)
from collections import defaultdict
class Solution:
def minWindow(self, s: str, t: str) -> str:
mem = defaultdict(int)
for char in t:
mem[char] += 1
t_len = len(t)
left = 0
minLeft = 0
minRight = len(s)
for right, char in enumerate(s):
if mem[char] > 0:
t_len -= 1
mem[char] -= 1
if t_len == 0:
while mem[s[left]] < 0:
mem[s[left]] += 1
left += 1
if right-left < minRight-minLeft:
minLeft, minRight = left, right
mem[s[left]] += 1
t_len += 1
left += 1
return '' if minRight==len(s) else s[minLeft:minRight+1]