滑动窗口模版

初始化慢指针 = 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
介绍相关的博文,很详细


leetcode      数组 滑动窗口

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!