给定一个由若干 0 和 1 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 。

返回仅包含 1 的最长(连续)子数组的长度。

输入:A = [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。
输入:A = [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. 1 <= A.length <= 20000
  2. 0 <= K <= A.length
  3. A[i] 为 0 或 1

方法一:二分

  因为0的个数是依此递增的,所以我们可以枚举区间i,j这个区间内0的个数要小于K

class Solution {
public:
int cnt[+];
int longestOnes(vector<int>& A, int K) {
for (int i=;i<=(int)A.size();++i){
cnt[i]=cnt[i-]+(A[i-]==);
}
int res=;
for (int i=;i<=(int)A.size();++i){
int l=i,r=(int)A.size(),ans=;
while (l<=r){
int mid=l+((r-l)>>);
if (cnt[mid]-cnt[i-]<=K){
l=mid+;
ans=mid-i+;
}
else r=mid-;
}
res=max(res,ans);
}
return res;
}
};

方法二:双指针

class Solution {
public:
int longestOnes(vector<int>& A, int K) {
int l=,r=,ans=,change=;
for(int i=;i<A.size();i++){
if(A[i]==){
if(change<K){
change++;
r++;
}
else{
while(l<=r&&A[l]!=)
l++;
l++;
r++;
}
}
else
r++;
ans=max(ans,r-l);
}
return ans;
}
};
05-11 19:31