滑动窗口问题
数组操作中有一个重要的方法:滑动窗口。
所谓滑动窗口,就是不断调节子序列的起始位置和终止位置,从而得到我们想要的结果。
在算法题中的应用场景:
关键词:
满足xxx条件(计算结果,出现次数,同时包含)
最长/最短
子串/子数组/子序列
例如:长度最小的子数组
通用思路
寻找最长:
核心:双指针left
和right
都在起始点,right
向右逐位开始滑动循环。在每次滑动过程中:
- 如果窗口内元素满足条件,
right
向右扩大窗口,并更新最优结果 - 如果窗口内元素不满足条件,
left
向右缩小窗口
right
到达结尾。
寻找最短:
核心:双指针left
和right
都在起始点,right
向右逐位开始滑动循环。在每次滑动过程中:
- 如果窗口内元素满足条件,
left
向右缩小窗口,并更新最优结果 - 如果窗口内元素不满足条件,
right
向右扩大窗口
right
到达结尾。
代码模板
寻找最长:
初始化left, result, bestResult
for(int right = 0; right < num.length; right++) {
窗口扩大,加入right对应元素,更新当前result
while (result不满足要求) {
窗口缩小,移除left对应元素,left右移
}
更新最优结果bestResult
}
return bestResult;
寻找最短:
初始化left, result, bestResult
for (int right = 0; right < nums.length; right++) {
窗口扩大,加入right对应元素,更新当前result
while (result满足要求) {
更新最优结果bestResult
窗口缩小,移除left对应元素,left右移
}
}
return bestResult;
leetcode209
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int result = Integer.MAX_VALUE;
int sum = 0;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= target) {
result = Math.min(result, right - left + 1);
sum -= nums[left++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}
参考自: