原题出处:https://leetcode.cn/leetbook/read/top-interview-questions-hard/xw1tws/
解法一(python):
from collections import defaultdict
class Solution:
def minWindow(self, s: str, t: str) -> str:
need = defaultdict(int)
window = defaultdict(int)
# 将 t 中的字符及其频率存储在 need 中
for c in t:
need[c] += 1
left, right = 0, 0
valid = 0
# 记录最小覆盖子串的起始索引及长度
start = 0
length = float('inf')
while right < len(s):
# c 是将移入窗口的字符
c = s[right]
# 扩大窗口
if c in need:
window[c] += 1
if window[c] == need[c]:
valid += 1
# 收缩窗口
while valid == len(need):
# 更新最小覆盖子串
if right - left + 1 < length:
start = left
length = right - left + 1
# d 是将移出窗口的字符
d = s[left]
# 缩小窗口
left += 1
# 进行窗口内数据的一系列更新
if d in need:
window[d] -= 1
if window[d] < need[d]:
valid -= 1
# 移动右指针
right += 1
# 返回最小覆盖子串
return "" if length == float('inf') else s[start:start+length]
思路:
这是一个经典的滑动窗口问题,可以使用滑动窗口来找到涵盖 t
中所有字符的最小子串。以下是解决这个问题的步骤:
- 初始化两个哈希表
need
和window
来记录t
中的字符和当前窗口中的字符及其频率。 - 初始化两个指针
left
和right
来表示滑动窗口的左右边界,初始时都指向字符串s
的开头。 - 初始化一个变量
valid
来记录当前窗口中满足t
中字符要求的字符个数,初始值为 0。 - 遍历
need
哈希表,将t
中的字符及其频率存储在need
中。 - 移动
right
指针,扩大窗口,并更新window
和valid
的值。 - 当
valid
的值等于need
哈希表中的键值对个数时,说明当前窗口已经包含了t
中的所有字符。 - 此时尝试缩小窗口,即移动
left
指针,并更新window
和valid
的值,同时记录当前窗口的大小(即right - left + 1
),并与之前记录的最小窗口大小进行比较。 - 重复步骤 5 到 7,直到
right
指针到达字符串s
的末尾。 - 返回最小窗口对应的子串,如果不存在这样的子串,则返回空字符串
""
。