leetcode1004
1.二分查找法
用一数组P【i】记录每个位置之前到自己本身位置i有多少个0,只要满足【left,ridht】之间的0个数小于等于k就可以连接成为连续的1。
即P【上界】-P【下界】<=k,枚举right,则要找到最小left就能够找到最长的连续1,P[right]-k<=P[left],则最小的left是P[right]-k;
因为第一个位置要是为0 要做特殊处理[上界,下界]之间0的个数不能简单用P[上界]-P【下界】,
记有n个元素,从P[0]~P[n+1],
P[0]=0;
P[i]=P[i-1]+(1-nums[i-1))//记录的是第i-1位置对应的0个数,防止在0位置i-1=-1边界溢出
下面讨论二分查找法:二分查找法去找下界
lower_bound()的实现,找到P[下届]>=P[上界]-k
for(int right=0;i<n;i++){ int left=lower_bound(nums.begin(),nums.end(),P[right+1]-k)-P.begin(); ans=max(ans,right-left+1); }
节约空间的方法:
用两个变量记录左右指针到达位置的0 的个数,我们要满足rsum-lsum>=k
要使left最小就要找到满足rsum-lsum>=k的最小left,即只要lsum<rsum-k就移动left指针,直到满足条件位置。插入1的位置是包括right之前的k个位置。
for(int right=0;right<n;++right){ rsum+=1-nums[right]; while(lsum<rsum-k){ lsum+=1-nums[left]; ++left; } ans=max(ans,right-left+1); }