数组刷题来到了第一个坎:数组中滑动窗口的应用。说实话,我个人还是觉得滑动窗口像是双指针的进阶版本(滑动窗口也有两个指针,只不过抽象角度看指针被具象化为窗口的两个边界了)
下面拿一个力扣上的经典例题来说明滑动窗口的应用
题号:209:《长度最小的子数组》
这道题的解题流程图和代码如下如下,其中双指针分别是start和end(ans表示临时记录的数组最小长度)
先上代码:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int n = nums.length;
if(n==0){
return 0;
}
int end = 0,start=0;
int ans = Integer.MAX_VALUE;
int sum = 0;
while(end < n){
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;
}
}
看完流程图可以发现这个算法非常的巧妙,由双指针组成的窗口先是从右边拉长,等到满足条件的时候再从左边缩短,这样变可以省去了暴力解法中一些不必要重复的比较(比如我已经比较过序号(不是下标!)1~3的元素不会大于target值了,那后续再判断2~3的元素就没有必要了,而暴力算法依旧会去判断)依据这样的拉伸控制窗口向前滑动(像蠕虫爬动一般)并且不断记录子数组的最小长度,最后得出答案!