滑动窗口算法核心思路
滑动窗口(Sliding Window)是处理数组或字符串区间问题的利器,本质上是同向双指针的一种优化应用。相比暴力解法的双重循环,它通过维护一个动态窗口,避免了重复计算,将时间复杂度从 O(N^2) 降到了 O(N)。在实际解题中,我们通常使用 left 和 right 两个指针,它们都向右移动且不回退,根据题目条件决定何时收缩左边界或扩展右边界。
下面结合几个经典的 LeetCode 题目,看看如何在 Java 中落地这一思想。
长度最小的子数组
题目描述 给定一个包含正整数的数组和一个目标值 target,找出满足其和 ≥ target 的连续子数组的最小长度。如果不存在,返回 0。
解题思路 暴力解法需要双重循环遍历所有可能的区间,效率较低。观察发现,当窗口内元素和已经大于等于 target 时,继续扩大右边界只会让长度变长,不符合'最小'的要求。此时应该尝试收缩左边界,直到和小于 target 为止。
具体做法是使用 sum 记录当前窗口和,right 负责入窗口,left 负责出窗口。当 sum >= target 时更新最小长度,并不断移除 left 指向的元素。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int sum = 0;
int len = Integer.MAX_VALUE;
int n = nums.length;
for (int left = 0, right = 0; right < n; right++) {
sum += nums[right]; // 入窗口
while (sum >= target) {
len = Math.min(len, right - left + 1); // 更新结果
sum -= nums[left++]; // 出窗口
}
}
return len == Integer.MAX_VALUE ? 0 : len;
}
}
时间复杂度:O(N),空间复杂度:O(1)


