Leetcode - 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)时间内解决此问题的算法吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解1 2021/9/10 O(n)
import collections
from collections import defaultdict
def help_enough(ds: collections.defaultdict, dt: collections.defaultdict) -> bool:
'''
判断,ds够不够
'''
for x in dt.keys():
if ds.get(x) is None or ds[x]<dt[x]: return False
return True
def minWindow(s: str, t: str) -> str:
''''''
'''
s = "ADOBECODEBANC", t = "ABC"
用dict把t存下来,各个字母有几个,因为这题的匹配不需要按照t的顺序,只要有就行
l,r
r一直走,一边也存到一个dict,如果数量满足,保存当前最优解
然后l向右走,一边走,一边更新dict,直到数量不满足,同步更新最优解
然后r继续向前,
往复
这个动作就好像一个虫子在爬一样,简直一模一样
'''
lens=s.__len__()
lent=t.__len__()
if lens<lent: return ''
dt=defaultdict(int)
for x in t:
dt[x]+=1
l=r=0
res=''
ds=defaultdict(int)
ds[s[r]]+=1
while l<lens and r<lens:
# 虫子头往前伸
while r<lens and help_enough(ds,dt)==False:
r+=1
if r<lens:
ds[s[r]]+=1
if r<lens:
# 题目限定了只有唯一解
if res=='' or r+1-l<res.__len__(): res=s[l:r+1]
# 虫子屁股往前伸
while l<=r and help_enough(ds,dt)==True:
ds[s[l]]-=1
l+=1
if res!='' and r+1-(l-1)<res.__len__(): res=s[l-1:r+1]
return res
if __name__ == '__main__':
# "BANC"
s = "ADOBECODEBANC"; t = "ABC"
print(minWindow(s,t))
# "a"
s = "a"; t = "a"
print(minWindow(s,t))
# ""
s = "a"; t = "aa"
print(minWindow(s,t))
s = "aaababa"; t = "aa"
print(minWindow(s,t))
s = "aaababa"; t = "ba"
print(minWindow(s,t))
s = "caababa"; t = "bac"
print(minWindow(s,t))
s = ""; t = "bac"
print(minWindow(s,t))


浙公网安备 33010602011771号