给定一个二进制数组 nums
和一个整数 k
,如果可以翻转最多 k
个 0
,则返回 数组中连续 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。
输入: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
解题思路:
滑动窗口(力扣)
- 重点:题意转换。把「最多可以把 K 个 0 变成 1,求仅包含 1 的最长子数组的长度」转换为 「找出一个最长的子数组,该子数组内最多允许有 K 个 0 」。
经过上面的题意转换,我们可知本题是求最大连续子区间,可以使用滑动窗口方法。滑动窗口的限制条件是:窗口内最多有 K 个 0。
可以使用我多次分享的滑动窗口模板解决,模板在代码之后。
代码思路:
- 使用
left
和right
两个指针,分别指向滑动窗口的左右边界。 right
主动右移:right
指针每次移动一步。当A[right]
为0
,说明滑动窗口内增加了一个0
;left
被动右移:判断此时窗口内0
的个数,如果超过了K
,则left
指针被迫右移,直至窗口内的0
的个数小于等于K
为止。- 滑动窗口长度的最大值就是所求
代码如下:
class Solution {
public:
int longestOnes(vector<int>& nums, int k){
int l = 0,len = 0,zeros = 0;
for(int r = 0;r < nums.size() ; ++r){
if(nums[r] == 0) zeros++;
while(zeros > k){
if(nums[l++] == 0) zeros--;
}
len = max(len,r - l + 1);
}
return len;
}
};