4.26 滑动窗口
1.滑动窗口(本质是数组快慢指针的一部分)
1.1 框架
int left = 0, right = 0;
// 滑动窗口算法伪码框架
void slidingWindow(String s) {
// 用合适的数据结构记录窗口中的数据,根据具体场景变通
// 比如说,我想记录窗口中元素出现的次数,就用 map
// 如果我想记录窗口中的元素和,就可以只用一个 int
Object window = ...
int left = 0, right = 0;
while (right < s.length()) {
// c 是将移入窗口的字符
char c = s[right];
window.add(c)
// 增大窗口
right++;
// 进行窗口内数据的一系列更新
...
// *** debug 输出的位置 ***
// 注意在最终的解法代码中不要 print
// 因为 IO 操作很耗时,可能导致超时
printf("window: [%d, %d)\n", left, right);
// ***********************
// 判断左侧窗口是否要收缩
while (left < right && window needs shrink) {
// d 是将移出窗口的字符
char d = s[left];
window.remove(d)
// 缩小窗口
left++;
// 进行窗口内数据的一系列更新
...
}
}
}
1.2 区间(很重要)
滑动窗口是一个左闭右开的区间,可以从初始化理解(left=right=0),所以一开始窗口里是没有元素的
1.3 时间复杂度O(n)
1.4 需要思考的几个问题
(1)什么时候扩大窗口,窗口加入字符时,应该更新哪些数据
(2)什么时候窗口应该暂停扩大,开始移动left缩小窗口,从窗口移除数据时,应该更新哪些数据
(3)我们要的结果应该在扩大窗口时还是缩小窗口时
例题
1.最小覆盖子串
思维启示:

必须判断两个条件同时成立,valid才能++,不然会出现重复的字符(本来不该+的,但是因为少了第二个条件判断导致+了)

浙公网安备 33010602011771号