一、简介
上一篇文章我们说了二分法的实际应用,二分法用于查找某个特俗位置时很好用,但是实际问题中,还有很多情况是要求我们要在一个固定数组中查找一串数满足某个固定条件,比如你肯定遇到过这样一个问题(额,暂时没有想到生活中的实际问题,先空着)那么滑动窗口主要就是用来解决这样的问题,在固定数组中查找特殊数组
二、问题
最小覆盖字串
分析:这是力扣上关于滑动窗口非常经典的一题,那么这题的思路其实也是简单,所谓滑动窗口,你可以想象成是一个窗户,A这一半在另一半B上滑动,求满足情况的位置,很显然我们需要俩个容器,windows表示当前滑动窗口中的数,need满足条件的每个字符的个数,need比较绕,是满足条件的每个字符个数,比如目标字符是"ABC",那么need就是{A:1,B:1,C:1},三个变量left,right表示当前滑动窗口左右段,和vaild(滑动窗口满足的字符个数)。
再想象滑动的俩种情况一种是,一种是windows未满足条件,则窗口继续向右滑动,即right++,如果windows满足条件了,这时让left++,减小窗口大小直到不满足,即满足了缩小窗口,不满足扩大窗口,这样不断滑动,就可以得到最终解了。
代码:
func minWindow(s string, t string) string {
window := make(map[byte]int, len(s))
need := make(map[byte]int, len(s))
left, right, vaid := 0, 0, 0
res := len(s)
star := 0
flag := false
for i := 0; i < len(t); i++ {
need[t[i]]++
}
for right < len(s) {
c := s[right]
if need[c] != 0 {
window[c]++
if need[c] == window[c] {
vaid++
}
}
right++
for vaid == len(need) {
flag = true
if right-left < res {
star = left
res = right - left
}
if need[s[left]] != 0 {
if window[s[left]] == need[s[left]] {
vaid--
}
window[s[left]]--
}
left++
}
}
if !flag {
return ""
}
return s[star : star+res]
}
这里为了提高程序的效率,同类问题让left单次滑动的次数越多越好
拓展
可以想一下kmp,还有最大公共字串,最大递增子序列(动态规划),这样做比较就能得出,什么情况下用哪种算法更好了
总结
想象成窗子,就俩个容器,俩种情况,三个变量