滑动窗口算法详解
滑动窗口的本质是用两个指针维护一个动态区间,通过移动指针来扩大或缩小窗口,在一次遍历中完成计算。其时间复杂度通常为 O(n)。
典型应用场景包括:寻找最长无重复字符的子串、找到和为目标值的最短子数组、字符串的排列匹配等。
通用模板思路
- 定义
left和right指针同时指向起始位置; right向右移动进窗口,模拟数据加入;- 当不满足要求时,
left向右移动出窗口,移除数据; - 根据具体情况更新结果。
结束条件通常是 right 越界。下面通过几道经典题目来巩固这一思想。
长度最小的子数组
题目描述
给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0。

核心思路
由于数组元素均为正整数,求和具有单调性,可以直接套用滑动窗口模板:
- 定义
left和right指针,同时指向首元素; right指针向右移动,进窗口,累加sum。当sum >= target时,尝试收缩窗口以更新最小长度;left指针向右移动,出窗口,同时让sum减去nums[left],直到sum < target。
注意:在收缩窗口(出窗口)的过程中,只要当前窗口仍满足
sum >= target,就需要持续更新结果,因为更小的窗口可能更优。
参考代码
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left = 0, right = 0;
int len = INT_MAX, sum = 0;
while (right < nums.size()) {
sum += nums[right]; // 进窗口,求和
(sum >= target) {
len = (len, right - left + );
sum -= nums[left++];
}
right++;
}
len == INT_MAX ? : len;
}
};






