算法入门(一):滑动窗口之允许重置的窗口
- 允许重置的窗口
- 模板
- [LeetCode 674 最长连续递增序列](#LeetCode 674 最长连续递增序列)
- [LeetCode 1446 连续字符](#LeetCode 1446 连续字符)
- [LeetCode 485 最大连续1的个数](#LeetCode 485 最大连续1的个数)
允许重置的窗口
例如 Leetcode 485 / 1446 / 674 这类题目,其本质是可变窗口。
- 条件一旦被破坏,左指针直接跳到右指针位置,不逐步收缩
- 仔细来说,窗口的条件只和
当前连续段有关。一旦破坏即重置,前面的窗口作废,而不需要用while逐步收缩。
下图体现了重置的过程:

1 是初始状态;
2 遇到了破坏条件;
3 left移动到right,right重新开始滑动,建立新窗口。
模板
cpp
left = 0;
right = 0;
for( ;right < n;right++){
if ( ) left = right;// 1.不满足条件重置
maxRes = max(maxRes , right - left + 1) // 2.计算连续长度
}
LeetCode 674 最长连续递增序列
按照模板思考:
1.寻找不满足条件:当nums[i]>=nums[i+1],即不满足递增序列
2.考虑边界条件:如果right从1开始,则right <n ,且要向前比较,即比较numsright和numsright-1;
如果right从0开始,则right < n -1,此时是向后比较,即比较 numsright 和 numsright+1;
cpp
// 方式1:和前面比(推荐)
for(int i = 1; i < n; i++){
if(nums[i] > nums[i-1]) { ... }
}
// 方式2:和后面比
for(int i = 0; i < n-1; i++){
if(nums[i+1] > nums[i]) { ... }
}
3.更新连续长度
LeetCode 1446 连续字符
同上,寻找破坏条件,即 s[right] != s[right-1],注意边界问题。
LeetCode 485 最大连续1的个数
简单做的话,是可以用cnt来统计连续1的个数的。
因为本文旨在练习同类题目,于是给出模板写法:
cpp
class Solution {
public:
int findMaxConsecutiveOnes(vector<int>& nums) {
int left = 0;
int right = 0;
int cnt = 0;
int maxCnt = 0;
for( ; right < nums.size();right++){
if(right > 0 && nums[right] != nums[right-1]) // 向前比较
{
left = right;
}
cnt = right - left + 1;
maxCnt = max(cnt,maxCnt);
}
return maxCnt;
}
};
注意一定要if判断条件里一定要写 right > 0。