滑动窗口算法详解
滑动窗口是一种常用的双指针技巧,通过维护一个动态的区间来解决问题。相比暴力枚举,它通常能将时间复杂度优化至 O(n)。其核心在于利用两个指针(left 和 right)控制窗口的扩大与缩小,在一次遍历中完成计算。
典型场景:寻找最长无重复字符的子串、找到和为目标值的最短子数组、字符串排列匹配等。
通用思路模板
- 定义 left 和 right 指针,初始均指向起始位置;
- 右指针向右移动扩大窗口,同时更新当前状态(如求和、计数);
- 当窗口不满足条件时,左指针向右移动缩小窗口,直到满足要求;
- 在合法状态下更新最终结果。
结束条件通常是 right 指针越界。下面我们通过四个经典题目来深入理解这一思想。
209. 长度最小的子数组
题目描述
给定一个含有 n 个正整数的数组和一个正整数 target,找出该数组中满足其和 ≥ target 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

实现核心及思路
由于数组元素均为正整数,累加和具有单调性。我们可以套用上述模板:
- 初始化 left 和 right 指针,以及当前和 sum 与最小长度 len;
- right 指针不断右移,将元素加入 sum;
- 一旦 sum >= target,说明当前窗口可能是一个解,尝试收缩左边界以寻找更小的长度;
- 在收缩过程中持续更新 len,直到 sum < target。
注意:在出窗口(left 右移)的过程中,只要 sum 仍满足条件,就要继续更新结果,因为此时窗口更小但依然合法。
思路可视化

C++ 代码实现
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left = 0, right = ;
len = INT_MAX, sum = ;
(right < nums.()) {
sum += nums[right];
(sum >= target) {
len = (len, right - left + );
sum -= nums[left++];
}
right++;
}
len == INT_MAX ? : len;
}
};







