发现滑动窗口也是一种经典解题思路,这一篇简单聊一下滑动窗口。
通常在碰到求XX子数组,子字符串,连续XX等题眼,可以考试用滑动窗口的思路来解决问题。
窗口的类型有几种:
1. 固定长度的窗口。
2. 窗口大小未知,求最大/最小长度的窗口。
不管是可变窗口还是固定窗口,核心思路需要指定左右指针 left 和 right。
核心思路是:
1. left = 0, 窗口的起点默认是数组的起点。
2. right 根据条件初始化,即 right - left + 1 为窗口大小(固定窗口) 或者是 right = 0(可变窗口)
3. 每一次循环中left 和 right 同时移动(固定窗口),只移动 right,只有当left满足条件时才移动(可变窗口)
4. 每次循环都判断当前窗口内的元素是否满足要求,如果是求最优解,可以继续循环直到得到最优解。
举个例子(https://leetcode-cn.com/problems/longest-subarray-of-1s-after-deleting-one-element/)
给你一个二进制数组 nums ,你需要从中删掉一个元素。
请你在删掉元素的结果数组中,返回最长的且只包含 1 的非空子数组的长度。
如果不存在这样的子数组,请返回 0 。
标准的滑动窗口的题目,而且是可变窗口!从核心思路来看,就是 left 和 right 初始化为0,根据条件变更 left 和 right 的位置。
class Solution { public int longestSubarray(int[] nums) { int res = 0, sum = 0; int left = 0; for(int right = 0;right<nums.length;right++){ sum += (nums[right]&1); while(left<right && sum <= right - left-1){ if(nums[left]==1) sum--; left++; } res = Math.max(res,right-left); } return res; } }