在保证滑动窗口的大框架下,使用类似于信号量的思想,让 t 在初始化的时候“占用”信号量,后面随着滑窗的扩展逐渐调整信号量的使用。
class Solution:
def minWindow(self, s: str, t: str) -> str:
valid = 0
need = dict()
for c in t:
need.setdefault(c, 0)
need[c] += 1
valid -= 1
window = dict()
left = right = 0
start = 0
end = 1000001
sz = len(s)
while right < sz:
c = s[right]
right += 1
if need.get(c):
window.setdefault(c, 0)
window[c] += 1
if window[c] <= need[c]: # 仿照信号量的设计
valid += 1
while valid >= 0:
if right - left < end - start:
start = left
end = right
c = s[left]
if need.get(c):
if window[c] <= need[c]: # 仿照信号量的设计
valid -= 1
window[c] -= 1
left += 1
if end - start == 1000001:
return ''
else:
return s[start:end]
window[c] <= need[c]
这一句的意思是,超出需要的部分就不构成有效数据了。其中很值得玩味的是一对镜像的操作,这也是仿照信号量的设计,释放要等全部操作完再释放,但占用却是先占用,这样才能确保数据安全。