滑动窗口算法简介
滑动窗口算法是笔试面试及算法竞赛中常见的算法,通常用于处理数组和字符串问题,尤其适合寻找满足特定条件的子数组或子字符串,以及连续子问题的计算。
滑动窗口的核心在于维护一个区间(窗口),其大小可以是固定的也可以是变化的。窗口在数据结构上移动来扫描数据。基本套路如下:
- 进窗口:将元素加入窗口。
- 判断条件:根据题意分析是否满足条件。
- 更新结果:若满足条件则更新最优解。
- 出窗口:移除不需要的元素以收缩窗口。
相关例题
长度最小的子数组
题目描述
给定一个含有 n 个正整数的数组和一个正整数 target。
找出该数组中满足其总和大于等于 target 的长度最小的 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
提示:
1 <= target <= 10^91 <= nums.length <= 10^51 <= nums[i] <= 10^4
实现思路
本题是典型的滑动窗口应用。暴力解法时间复杂度为 O(n^2),会超时。优化方案包括前缀和加二分查找 O(n log n),或使用滑动窗口达到 O(n)。
- 定义左右指针指向开头,初始化最大长度为无穷大。
- 右指针右移,将值加入窗口。
- 当窗口和大于等于目标值时,更新结果长度,左指针右移收缩窗口。
- 继续移动右指针直到结束。
实现代码
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.(), sum = , len = INT_MAX;
( left = , right = ; right < n; right++) {
sum += nums[right];
(sum >= target) {
len = (len, right - left + );
sum -= nums[left++];
}
}
len == INT_MAX ? : len;
}
};


