给定一个由若干 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[20000+10]; int longestOnes(vector<int>& A, int K) { for (int i=1;i<=(int)A.size();++i){ cnt[i]=cnt[i-1]+(A[i-1]==0); } int res=0; for (int i=1;i<=(int)A.size();++i){ int l=i,r=(int)A.size(),ans=0; while (l<=r){ int mid=l+((r-l)>>1); if (cnt[mid]-cnt[i-1]<=K){ l=mid+1; ans=mid-i+1; } else r=mid-1; } res=max(res,ans); } return res; } };
方法二:双指针
class Solution { public: int longestOnes(vector<int>& A, int K) { int l=0,r=0,ans=0,change=0; for(int i=0;i<A.size();i++){ if(A[i]==0){ if(change<K){ change++; r++; } else{ while(l<=r&&A[l]!=0) l++; l++; r++; } } else r++; ans=max(ans,r-l); } return ans; } };