1.题目描述

2.思路
如果有元素之间有相对顺序关系的话,不建议使用hashmap
(1)不定长滑动窗口:
不定长滑动窗口主要分为三类:求最长子数组,求最短子数组,求子数组个数。
注:滑动窗口相当于在维护一个队列。右指针的移动可以视作入队,左指针的移动可以视作出队。
(2)删除后,子数组只有 1,也就是没有 0。那么删除之前呢?至多有一个 0。
(3)cnt = cnt - (1 - nums[left]);
如果将要移出窗口的 nums[left] 是 1,那么 1 - nums[left] 的结果是 0。cnt 不变(因为移出一个1对0的个数没有影响)。
如果将要移出窗口的 nums[left] 是 0,那么 1 - nums[left] 的结果是 1。cnt 减少 1(因为我们把一个0移出了窗口)。
所以,这行代码的作用是:当窗口移出一个 0 时,cnt 减一。
(4)当右指针 right 移动,元素进入窗口时:
执行 cnt = cnt + 1 - nums[right];
如果 nums[right] 是 1,那么 1 - nums[right] 的结果是 0。cnt 不变。
如果 nums[right] 是 0,那么 1 - nums[right] 的结果是 1。cnt 增加 1。
所以,这行代码的作用是:当窗口滑入一个 0 时,cnt 加一。
3.代码实现
java
class Solution {
public int longestSubarray(int[] nums) {
//1.左右指针都从0开始移动
int left=0;
int cnt=0;//存0的个数
int res=0;
for(int right=0;right<nums.length;right++)
{ //1-nums[right]:从左往右遍历记录0的个数。因为遇到1的时候:1-1=0;遇到0的时候为1-0=1;实现计数功能
//1.右指针进入窗口。当窗口滑入一个 0 时,cnt 加一。
cnt=cnt+1-nums[right];
while(cnt>1)//如果0的个数大于1,退出循环
{
//窗口末尾元素(最左边的元素)出队,nums[left]离开窗口
//当窗口移出一个 0 时,cnt 减一。
cnt=cnt-(1-nums[left]);
left++;
}
// 3. 更新答案,注意不是 right-left+1,因为我们要删掉一个数
res=Math.max(res,right-left);
}
return res;
}
}