滑动窗口模版
初始化慢指针 = 0
初始化 ans
for 快指针 in 可迭代集合
更新窗口内信息(通常是快指针逐增,也就是对右边界进行操作)
while 窗口内不符合题意
扩展或者收缩窗口(通常是对左边界进行操作)
慢指针移动
更新答案
返回 ans
看到题目想到要用滑动窗口法,关键词就在于“连续”,最后所求的大概率是一段连续子序列,同时不改变数组原来的位置。滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)的暴力解法降为O(n)。
209.长度最小的子数组
思路简述
题目中要求找出长度最小的连续子数组,那么就要想到用滑动窗口来解题的可能性。
这个题直接套模版就可以,快指针不断向右边界靠近,并实时判断此时快慢指针包括区间内的总和sum是否大于给定值val。
一旦大于,也就是快慢指针区间之间可以减少元素,那么就需要慢指针上场了。
首先记录此时的最小长度minlen是否为快慢指针之间的长度right-left+1。然后left右移,区间缩小,sum减小后再进行判断,如此循环。
public static int theminsubarraylen(int[] nums,int val) {
int minlen=Integer.MAX_VALUE;
int left=0;
int sum=0;
for(int right=0;right<nums.length;right++) {//右边界扩展
sum+=nums[right];
while(sum>=val) {//当不满足条件时,也就是需要满足保证sum>=val并且快慢指针区间长度最小
minlen=Math.min(minlen, right-left+1);
sum-=nums[left++];//快慢指针区间缩小
}
}
return minlen==Integer.MAX_VALUE?0:minlen;//务必要加这一句,不然当便利完整个数组依然不满足条件的时候,minlen不会被赋值,会是一开始赋的Integer.MAXVALUE的值
}
904.水果成篮
思路简述
这个题目的关键是读懂题意,本质上就是让求一段最长的连续子序列,这一段序列里只能出现两种数字。看到连续,想到滑动窗口解法。
主要思路还是可以套模版,但是因为要考虑到两种元素,要加上对map的运用。
public static int totalfruit(int[] nums) {
if(nums==null||nums.length==0)
return 0;
int len=nums.length;
Map<Integer,Integer> map=new HashMap<>();
int maxSum=0,left=0;
for(int right=0;right<len;right++) {
map.put(nums[right], map.getOrDefault(nums[right], 0)+1);
while(map.size()>2) {//当不符合条件时,也就是超过两种元素,调整左边界即慢指针
map.put(nums[left], map.get(nums[left])-1);
if(map.get(nums[left])<1) {
map.remove(nums[left]);
}
left++;
}
maxSum=Math.max(maxSum, right-left+1);
}
return maxSum;
}
https://github.com/azl397985856/leetcode/blob/master/thinkings/slide-window.md
介绍相关的博文,很详细
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!