给定一个二进制数组?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
//最大连续1的个数III
//二进制数组
//翻转k个0
//翻转不必连续
//求翻转后连续1的最大个数
//借助上一次翻转个数
//滑动窗口
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> nums;//二进制数组
int k;//最多翻转个数
int n;//二进制数组长度
int result = 0;//结果
//滑动窗口
void slidingWindow(){
int left = 0,right = 0;//左右指针
int ct = k;//还剩几次翻转机会
int res = 0;//当前左指针情况下的连续1的最大个数
//循环尝试左指针
for(;left < n;left++){
if(right >= n){
//右指针到头了
break;
}
while(ct > 0 || nums[right] == 1){
//右指针未到头,还可以翻转(或当前不需要翻转)
if(nums[right] == 0){
//需要翻转
ct--;
}
res++;
right++;
if(right >= n){
//右指针到头了
break;
}
}
result = max(result,res);
if(nums[left] == 0){
//要去掉的这个是0时
ct++;
}
res--;
}
}
int main(){
//输入整数数组
int t;
while(cin.peek() != '\n'){
scanf("%d",&t);
nums.push_back(t);
}
//输入最多翻转个数
scanf("%d",&k);
//-------------------------------
n = nums.size();//字符串长度
//滑动窗口
slidingWindow();
//输出结果
printf("%d",result);
return 0;
}
解题思路:题目求翻转后连续1的最大个数,属于连续一段元素的群体关系,可以使用滑动窗口(同向双指针),每次尝试固定左指针,借助上一个左指针得出的值,推断右指针。