1、滑动窗口的理解
滑动窗口也可以理解为双指针法的一种!只不过这种解法更像是一个窗口的移动,所以叫做滑动窗口更适合一些。
2、滑动窗口需要确定的三点
主要确定如下三点:
- 窗口内是什么?
- 如何移动窗口的起始位置?
- 如何移动窗口的结束位置?
3、209. 长度最小的子数组 - 力扣(LeetCode) (leetcode-cn.com)
窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,窗口的起始位置设置为数组的起始位置就可以了。
解题的关键在于 窗口的起始位置如何移动,如图所示:
可以发现滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)的暴力解法降为O(n)。
java实现:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
// int start=0,end = 0;
// int n = nums.length;
// int min = Integer.MAX_VALUE;
// while(start<n){
// while(end<n){
// int sum = 0;
// for(i = start;i<end+1;i++){
// sum+=nums[i];
// }
// if(sum<target)end++;
// else {
// min = Mah.min(min,end-start+1);
// start++;
// }
// }
// }
// return min;
//暴力解决
// int len = nums.length;
// int sum = 0;
// int tmpLen = Integer.MAX_VALUE;
// for(int i=0; i<len; i++){
// sum = 0;
// for(int j=i; j<len; j++){
// sum += nums[j];
// if(sum>=target) tmpLen = Math.min(j-i+1,tmpLen);
// }
// }
// return tmpLen==Integer.MAX_VALUE ? 0:tmpLen;
//滑动窗口
int len = nums.length;
if(len == 0)return 0;
int ans = Integer.MAX_VALUE;
int start = 0, end= 0;
int sum = 0;
while(end<len){
sum += nums[end];
while(sum >= target){
ans = Math.min(ans, end - start + 1);
sum -= nums[start];
start++;
}
end++;
}
return ans == Integer.MAX_VALUE ? 0:ans;
}
}