网络异常,图片无法展示
|
题目地址(76. 最小覆盖子串)
题目描述
给你一个字符串 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: from collections import Counter length = len(s) left,right,match = 0, 0,0 resLeft,resRight,minResLen = 0, 0,length+1 tDict = Counter(t) while right < length: #先右边扩张 # print(left, right, resLeft, resRight) # print([s[left:right+1]]) rS = s[right] # print(rS,tDict) if rS in tDict: tDict[rS] -= 1 if tDict[rS] >= 0: match += 1 #收缩条件 while match == len(t): #判断是否最短子串长度 if (right - left) < minResLen: # print([s[left:right + 1]],resRight,resLeft, minResLen) minResLen = min(minResLen,right-left) resLeft,resRight = left,right #左边在收缩,直到mtath<len(t) if left <= right: lS = s[left] if lS in tDict: tDict[lS] += 1 if tDict[lS] > 0: match -= 1 # print(lS, tDict) left += 1 right += 1 # print(left, right, resLeft, resRight) return s[resLeft:resRight+1] if minResLen != length+1 else "" if __name__ == '__main__': s = "ADOBECODEBANC" t = "ABC" s = "a" t = "a" result = Solution().minWindow(s,t) print(result)
复杂度分析
令 n 为数组长度。
- 时间复杂度:O(n)O(n)
- 空间复杂度:O(n)O(n)