1004. 最大连续1的个数 III
题目
给定一个二进制数组 nums
和一个整数 k
,如果可以翻转最多 k
个 0
,则返回 数组中连续 1 的最大个数 。
示例1
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。
示例2
输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。
提示
1 <= nums.length <= 105
nums[i]
不是0
就是1
0 <= k <= nums.length
分析
典型的滑动窗口题:
方法一:窗口左右边界为l和r,遍历数组,找0的个数,当0的个数为k+1时,左边界遍历找到一个0使窗口内0的个数保持在<=k。在继续遍历窗口,最后需判断最后一个窗口是否满足条件。
方法二:上述方法看似已经比较完美,但是对于寻找最大滑动窗口问题,你不必需要减少窗口的大小,只要维护当前最大窗口即可。即遍历r,遇到0,让k–,记录当前窗口是否满足条件;当k<0不满足条件时候,不必减小窗口,而是让窗口左边界和右边界同时向右走。若找到更大的窗口,因为满足条件,左边界不会向右走。最后返回r-l即获得的最大窗口即可。
代码
public class Solution {
public int longestOnes(int[] nums, int k) {
int l=0, r=0;
int length = nums.length;
int curCount=0, curK=0;
int count = 0;
while (r<length){
curK += nums[r]==1 ? 0 : 1;
if (curK>k) {
count = Math.max(count, r-l);
while (l<=r && nums[l++]==1);
curK--;
}
r++;
}
count = Math.max(count, r-l);
if (curK<k) count = nums.length;
return count;
}
}
public class Solution {
public int longestOnes(int[] nums, int k) {
int l=0, r=0;
while (r<nums.length) {
if (nums[r++]==0) k--;
if (k<0 && nums[l++]==0) k++;
}
return r-l;
}
}
结果
时间超过100%
内存超过74%