滑动窗口是处理数组或字符串子串问题的利器。核心思想是用两个指针维护一个动态区间,通过移动指针扩大或缩小窗口,在一次遍历中完成计算,时间复杂度通常为 O(n)。
典型应用场景包括寻找最长无重复字符的子串、找到和为目标值的最短子数组等。基本套路是定义左右指针,根据条件移动右指针进窗口,不满足条件时移动左指针出窗口,并实时更新结果。
1. 长度最小的子数组
问题描述: 给定一个含有 n 个正整数的数组和一个正整数 target,找出该数组中满足其和 ≥ target 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
思路解析: 由于数组元素均为正整数,累加和具有单调性,非常适合套用滑动窗口模板。
- 定义 left 和 right 指针,初始指向首元素。
- right 指针向右移动,将元素加入窗口并累加 sum。当 sum >= target 时,说明当前窗口合法,尝试更新最小长度。
- 在满足条件的前提下,left 指针向右移动,移除元素并减少 sum,直到 sum < target,从而收缩窗口以寻找更优解。
这里有个细节:在收缩窗口的过程中(即 while 循环内),只要 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]; // 进窗口,求和
while(sum >= target) { // 保证窗口合法
len = min(len, right - left + 1); // 更新结果
sum -= nums[left++]; // 出窗口
}
right++;
}
len == INT_MAX ? : len;
}
};




