mirror of
https://github.com/heqin-zhu/algorithm.git
synced 2024-03-22 13:30:46 +08:00
Add min-window-substring using sliding window
This commit is contained in:
parent
936d05bb32
commit
247df5fb71
58
dataStructure/insert_remove_getRandom.py
Normal file
58
dataStructure/insert_remove_getRandom.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : insert_remove_getRandom.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.xyz
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2019-05-24 10:01
|
||||
# Description:
|
||||
insert, remove, getRandom 的摊还时间为 O(1),
|
||||
且有重复数据, remove 一次删除一个元素
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
class RandomizedCollection:
|
||||
def __init__(self):
|
||||
|
||||
self.vals=[]
|
||||
self.index={}
|
||||
|
||||
def insert(self, val: int) -> bool:
|
||||
self.vals.append(val)
|
||||
if val in self.index:
|
||||
self.index[val].add(len(self.vals)-1)
|
||||
return False
|
||||
else:
|
||||
self.index[val] = {len(self.vals)-1}
|
||||
return True
|
||||
def removeAll(self, val: int) -> bool:
|
||||
if val not in self.index:
|
||||
return False
|
||||
begin = end = len(self.vals)-len(self.index[val])
|
||||
for idx in self.index.pop(val):
|
||||
if idx<begin:
|
||||
while self.vals[end]==val:
|
||||
end+=1
|
||||
self.vals[idx]=self.vals[end]
|
||||
self.index[self.vals[idx]].remove(end)
|
||||
self.index[self.vals[idx]].add(idx)
|
||||
self.vals = self.vals[:begin]
|
||||
return True
|
||||
def remove(self,val):
|
||||
if val not in self.index:
|
||||
return False
|
||||
last = len(self.vals)-1
|
||||
idx = self.index[val].pop()
|
||||
if len(self.index[val])==0:
|
||||
del self.index[val]
|
||||
if idx!=last:
|
||||
self.vals[idx] = self.vals[last]
|
||||
self.index[self.vals[idx]].remove(last)
|
||||
self.index[self.vals[idx]].add(idx)
|
||||
self.vals.pop()
|
||||
return True
|
||||
def getRandom(self) -> int:
|
||||
if self.vals:
|
||||
return self.vals[random.randint(0,len(self.vals)-1)]
|
60
string/min-window-substring.py
Normal file
60
string/min-window-substring.py
Normal file
|
@ -0,0 +1,60 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : min-window-substring.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.xyz
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2019-05-26 21:39
|
||||
# Description:
|
||||
from leetcode-cn #76: https://leetcode-cn.com/problems/minimum-window-substring/
|
||||
|
||||
给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。
|
||||
输入: S = "ADOBECODEBANC", T = "ABC"
|
||||
输出: "BANC"
|
||||
说明:
|
||||
如果 S 中不存这样的子串,则返回空字符串 ""。
|
||||
如果 S 中存在这样的子串,我们保证它是唯一的答案。
|
||||
|
||||
since you have to find the minimum window in S which has all the characters from T, you need to expand and contract the window using the two pointers and keep checking the window for all the characters. This approach is also called Sliding Window Approach.
|
||||
|
||||
L ------------------------ R , Suppose this is the window that contains all characters of T
|
||||
L----------------- R , this is the contracted window. We found a smaller window that still contains all the characters in T
|
||||
|
||||
When the window is no longer valid, start expanding again using the right pointer.
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
from collections import defaultdict
|
||||
class Solution:
|
||||
def minWindow(self, s: str, t: str) -> str:
|
||||
def expand(j,lacked,dic):
|
||||
while j<n and lacked:
|
||||
if s[j] in lacked:
|
||||
lacked[s[j]]-=1
|
||||
if lacked[s[j]]==0:
|
||||
del lacked[s[j]]
|
||||
dic[s[j]]+=1
|
||||
j+=1
|
||||
return j
|
||||
def contract(left,right):
|
||||
for i in range(left,right):
|
||||
dic[s[i]]-=1
|
||||
if dic[s[i]]==0:
|
||||
del dic[s[i]]
|
||||
if s[i] in chars and (s[i] not in dic or dic[s[i]]<chars[s[i]]):
|
||||
return i+1,{s[i]:1}
|
||||
n ,i, j= len(s),0,0
|
||||
ans = ''
|
||||
dic,lacked = defaultdict(int), defaultdict(int)
|
||||
for c in t:
|
||||
lacked[c]+=1
|
||||
chars = lacked.copy()
|
||||
while j<n and lacked:
|
||||
j = expand(j,lacked,dic)
|
||||
if not lacked:
|
||||
i,lacked=contract(i,j)
|
||||
if ans=='' or len(ans)>j-i+1:
|
||||
ans = s[i-1:j]
|
||||
return ans
|
Loading…
Reference in New Issue
Block a user