题目
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
Python实现
import sys
def longest_dup_substr(s, t):
# 构造需要匹配t的字符串的数量字典
need_map = {}
for c in t:
need_map[c] = need_map.get(c, 0) + 1
# 记录窗口已经匹配的字符串数量
window_map = {}
# 记录已经满足need_map的数量
match_cnt = 0
# 需要匹配的数量和已经匹配的数量
need_cnt = len(need_map)
left = 0 # 窗口左边界
right = 0 # 窗口边右界
start = 0 # 记录匹配的起点
min_len = sys.maxsize # 记录匹配的最小距离
while right < len(s):
c = s[right]
# 如果匹配
if c in need_map:
# 更新窗口匹配字符数量
window_map[c] = window_map.get(c, 0) + 1
# 如果该字符串数量达标,更新match_cnt
if window_map[c] == need_map[c]:
match_cnt += 1
# 右移窗口
right += 1
# 如果全部数量达标,收缩窗口,并更新起点和距离
while match_cnt == need_cnt:
if right - left < min_len:
start = left # 记录匹配的起点
min_len = right - left # 记录匹配的最小距离
# 定位左边要移除的字符
d = s[left]
# 如果在匹配的字符里,更新窗口,减少匹配数量
if d in window_map:
if window_map[d] == need_map[d]:
match_cnt -= 1
window_map[d] -= 1
# 收缩左边窗口
left += 1
# 没匹配到,返回空字符串
if min_len == sys.maxsize:
return ""
return s[start:start + min_len]
s = "ADOBECODEBANC"
t = "ABC"
res = longest_dup_substr(s, t)
print(res)