题目链接
https://leetcode.com/problems/minimum-window-substring/
题目描述
给定一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。如果 s 中存在这样的子串,能够保证它是唯一的答案。
示例
输入:s=“aab”,t="aa"
输出:“aa”
解题思路
滑动窗口属于双指针算法的一种, 适合解决子串问题(查找满足一定条件的连续区间的性质(如长度)的问题)。在滑动窗口算法中需要维护一个窗口,并让窗口在字符串上游走。具体实现时需要维护两个指针l和r,表示滑动窗口的左边界和右边界,滑动窗口为左闭右开区间[l,r)。l和r初始化为0,此时滑动窗口长度为0。
滑动窗口要如何在字符串上移动呢?我们首先移动右指针r不断扩张窗口,移动到[l,r)滑动窗口内的元素满足题目要求。然后我们再移动左指针l收缩窗口,直到滑动区间不再符合题目要求。然后再继续移动r,...循环操作直到r到达字符串的终点。在这个过程中我们不断更新当前最优值。
我们可以得出,r指针用来延伸现有窗口,找到可行解;l指针用来收缩窗口,优化这个可行解。在滑动窗口游走的任意时刻,只有一个指针在移动,而另一个保持静止。随着左右指针不断前进,窗口不断向右滑动。
用滑动窗口问题解决最短子串问题的代码模板可以总结为:
def slidingWindow(s):
#初始化左指针和右指针(左闭右开区间)
l,r = 0,0
while r<len(s):
#r右移,c为即将加入窗口的字符
c = s[r]
r += 1
#更新窗口内的数据
#TODO
#print(left,right) #在这里打印区间可以用来debug
#判断是否移动l指针收缩窗口
while (得到一个可行解,满足收缩条件):
#窗口内是可行解,更新最优解
#TODO
#l左移
d = s[l]#l为即将被移出窗口的字符
l += 1
#更新窗口内的数据
#TODO
return最优值并处理找不到最优值的