简要介绍
滑动窗口是笔试面试以及算法竞赛中处理数组和字符串问题的常用技巧,特别适合寻找满足特定条件的子数组或子串。窗口大小可以是固定的也可以是变化的,通过左右指针的移动来扫描数据结构。
基本套路通常包含四个步骤:
- 扩大窗口:右指针移动,将新元素纳入窗口。
- 检查条件:判断当前窗口是否满足题目要求。
- 更新结果:若满足条件,记录最优解。
- 收缩窗口:左指针移动,移除旧元素以尝试更优解。
相关例题
长度最小的子数组
题目描述
给定一个含有 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²),在数据量较大时会超时。虽然可以用前缀和加二分查找优化到 O(n log n),但滑动窗口能直接达到 O(n)。
核心逻辑是维护一个和大于等于 target 的窗口。当窗口和满足条件时,尝试收缩左边界以找到最小长度;若不满足,则继续扩张右边界。
代码实现
class Solution {
public:
int minSubArrayLen(int target, vector<>& nums) {
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;
}
};


