滑动窗口的特征
窗口由两个指针(通常称为左指针和右指针)定义,维护一个动态大小的窗口
滑动窗口的简单图解
简单的例子:有A - H的连续按字母表升序的字符串,需要找到同时包含DEF的最小子字符串。
以下图解流程为滑动窗口的初始定义以及滑动的一个过程。(初始化、扩大边界、缩小边界)
1、维护2个指针start和end,同时指向A。start和end为窗口的边界。

2、开始向右移动end到B,得到窗口AB。发现窗口没有包含DEF,持续移动end,扩大右边界。

3、继续向右移动end,扩大右边界,一直移动到F,得到窗口A- F,同时包含DEF。

4、向右移动start,缩小左边界,得到同时包含DEF的最小窗口D-F

滑动窗口的应用场景
1、寻找字符串中的最小覆盖子串
2、计算数组中满足特定条件的子数组数量
3、最长无重复子串
4、时间滑动窗口:限流、计数统计等
题型思考
题目:无重复字符的最长子串
举例分析字符串:ababcaac
1、初始存储一个map,记录字符是否出现过

2、移动right,一直移动到c,发现下一个a在map{a,b,c}中出现过,停止right的移动,记录此时的子串长度。

3、移动left,并从map中删除掉a,此时map为{b,c}

4、重复以上2轮步骤,移动right找到右边界,然后再移动left,缩小边界,再移动right,扩大右边界,循环一直到结束,记录最大的子串长度。
代码如下:
func lengthOfLongestSubstring(s string) int {
// 记录每个字符是否出现过
recordMap := map[byte]int{}
n := len(s)
// 右指针,初始值为 -1,相当于字符串的左边界的左侧
rightIndex, result := -1, 0
for i := 0; i < n; i++ {
if i != 0 {
// 左指针向右移动一格,移除掉之前的字符
delete(recordMap, s[i-1])
}
for rightIndex+1 < n && recordMap[s[rightIndex+1]] == 0 {
// 不断地移动右指针
recordMap[s[rightIndex+1]]++
rightIndex++
}
// 无重复字符子串长度: 第 i 到 rightIndex 个字符
result = max(result, rightIndex-i+1)
}
return result
}
1万+

被折叠的 条评论
为什么被折叠?



