1. 滑动窗口简介
滑动窗口是一种在算法中常用的技巧,主要用来处理具有连续性的子数组或子序列问题。通过滑动窗口,可以在一维数组或字符串上维护一个固定或可变长度的窗口,逐步移动窗口,避免重复计算,从而提升效率。常用于求解子数组的最大/最小值、满足条件的子数组个数等问题。
滑动窗口的两种类型
1. 固定大小的滑动窗口:窗口大小固定不变,通常适合于问题中要求找定长子数组的最大值、最小值等情况。
2. 可变大小的滑动窗口:窗口大小根据条件动态调整,通常适用于子数组和达到一定值或满足特定条件的情况。
滑动窗口的实现步骤
以可变大小的滑动窗口为例,一般步骤如下:
1. 初始化窗口的左右边界(例如 `left` 和 `right` 指针),并根据问题需求定义窗口内需要维护的变量(如窗口内的和、计数等)。
2. 移动右边界 `right`,将新元素加入窗口,并更新窗口内的变量。
3. 检查当前窗口是否满足条件。如果满足,记录答案(如更新最大/最小值),然后移动左边界 `left` 以缩小窗口,继续寻找其他符合条件的窗口。
4. 重复步骤 2 和 3,直到右边界遍历完数组。
应用场景
滑动窗口常用于以下几类问题:
- 子数组和问题(如最大、最小和)
- 子字符串问题(如最长无重复子串)
- 符合条件的区间统计
这种方法在处理需要频繁访问连续子序列的问题时具有高效性。
2. 长度最小的子数组
一、题目介绍
二、思路解析
方法一:暴力枚举
枚举 将数组中的每个元素 都当做起点,向后遍历数组寻找最短区间,最后找到将所有元素当做期待所得结果的最小值。
优化方法:滑动窗口 :
由于此问题分析的对象是「⼀段连续的区间」,因此可以考虑「滑动窗口」的思想来解决这道题。
(1)left = 0, right = 0
(2)进窗口
- 当窗口中的值小于target是,进窗口
(3)判断什么时候出窗口并更新结果
- 当窗口中的值大于等于target时,窗口中的值减去left位置的值(更新结果),出窗口(left++)
三、代码实现
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size(), sum = 0, len = INT_MAX;
for (int left = 0, right = 0; right < n; right++)
{
sum += nums[right];//进窗口
while (sum >= target) // 判断
{
len = min(len, right - left + 1); // 更新结果
sum -= nums[left++]; // 出窗口
}
}
return len == INT_MAX ? 0 : len;
}
};