给定一个由若干 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 <= A.length <= 20000
0 <= K <= A.length
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;
}
};