滑动窗口算法概述
滑动窗口使用两个指针维护一个动态的'窗口'区间,通过移动指针来扩大或缩小窗口,在一次遍历中完成计算,时间复杂度通常为 O(n)。
典型应用:寻找最长无重复字符的子串、找到和为目标值的最短子数组、字符串的排列匹配。
一般步骤(模板):
- 定义 left 和 right 指针同时指向数组首元素;
- 当符合要求时,right++,模拟进窗口;
- 不满足要求时,left++,模拟出窗口;
- 并根据具体情况更新结果。
结束条件:当 right 越界。
209. 长度最小的子数组
题目描述
给定一个含有 n 个正整数的数组和一个正整数 target。找出该数组中满足其和 ≥ target 的长度最小的连续子数组 [numsl, numsl+1, ..., numsr-1, numsr],并返回其长度。如果不存在符合条件的子数组,返回 0。
实现核心及思路
由于数组元素均为正整数,求和时满足单调性,套用滑动窗口模板:
- 定义 left 和 right 指针,同时指向首元素;
- right 指针向右移动,进窗口,并求和 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]; // 求和
while(sum >= target) { // 保证窗口合法
len = min(len, right - left + 1); // 更新结果
sum -= nums[left++]; // 出窗口
}
right++; // 继续进窗口
}
return len == INT_MAX ? 0 : len;
}
};


