题目地址(76. 最小覆盖子串)
https://leetcode.cn/problems/minimum-window-substring/
题目描述
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
示例 2:
输入:s = "a", t = "a"
输出:"a"
示例 3:
输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。
提示:
1 <= s.length, t.length <= 105
s 和 t 由英文字母组成
进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?
前置知识
公司
- 暂无
思路
关键点
代码
- 语言支持:Python3
Python3 Code:
class Solution:
def minWindow(self, s: str, t: str) -> str:
"""
寻找最小子串
思路:
滑动窗口+哈希表
滑动窗口记录遍历过的信息,从而一次遍历完成;
哈希表记录子串的遍历情况
"""
# 创建一个need字典 表示需要匹配的字子串
need = collections.Counter(t)
# needCnt表示需要匹配的总个数
needCnt = len(t)
ans = float('inf')
min_l,min_r= -1,-1
l = 0
for r in range(len(s)):
# 如何区分哪些是真正需要的
# 对于存在need中的元素 执行减一操作
# 如果value值大于0 那么needCnt也要减一
# 如果不存在need中 那么赋值为-1
if s[r] in need:
if need.get(s[r]) > 0:
needCnt -= 1
need[s[r]] -= 1
# 如果找到一个满足条件的子串 移动左窗口
if needCnt == 0:
while True:
if s[l] in need:
if need[s[l]] == 0:
break
else:
need[s[l]] += 1
l+=1
if r-l+1 < ans:
ans = r -l +1
min_l,min_r = l,r
needCnt += 1
need[s[l]] += 1
l+=1
return '' if min_l == -1 else s[min_l:min_r+1]
复杂度分析
令 n 为数组长度。
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)