1004. 最大连续1的个数 III

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

返回仅包含 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。

示例 2:

输入: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 

Solution One:

sliding window

在curZero<=K的条件下往右expand,当curZero>K的时候从左边shrink

值得一提的是当r指针到数组末尾的时候,如果数组末尾值是1,curOne就会少算1,所以采用A.append(1)的方法处理这种情况,同时也不会影响r指针在指到末尾之前就已经取得maxWindow的情况

class Solution:
    def longestOnes(self, A: List[int], K: int) -> int:
        if len(A)-sum(A)<=K:return len(A)
        l=r=maxWindow=curWindow=curZero=curOne=0
        A.append(1)
        while r<len(A):
            while curZero<=K and r<len(A):
                curWindow=curOne+curZero
                maxWindow=max(maxWindow,curWindow)
                if A[r]==0:
                    curZero+=1
                else:
                    curOne+=1
                r+=1
                while curZero>K:
                    if A[l]==0:
                        curZero-=1
                    else:
                        curOne-=1
                    l+=1          
        return maxWindow
            

这是比较直观的容易想到的解法,再来

 

Solution Two:

首先数1,如[1,1,1,0,0,0,1,1,1,0]计数变为[3,4],再加上一个数组[3]表示3,4中间有3个0,即只需将这3个0改为1,即可完成2个部分的拼接,然后:
1贪心:一定要把连续的0换成1,这样连起来的才是最长的。
2基本上转化为two pointer problem,找到一个滑动窗口,里面0的个数不超过K,1也是最多的

class Solution:
    def longestOnes(self, A: List[int], K: int) -> int:
        if len(A)-sum(A)<=K:return len(A)
        if sum(A)==0:return K
        profit=[]
        cost=[]
        i=0
        while i<len(A) and A[i]==0:i+=1
        while i<len(A):
            j = i
            while j<len(A) and A[j]==1: j+=1
            profit.append(j-i)
            k = j
            while k<len(A) and A[k]==0: k+=1
            cost.append(k-j)
            i = k
        cost.pop()

        res = K+max(profit)
        i = j = used = 0
        contig = profit[0]
        while j<len(cost):
            while j<len(cost) and K-used>=cost[j]:
                used+=cost[j]
                contig += profit[j+1]  
                j+=1
            if i==j:
                i+=1
                j+=1
                continue
            res=max(res,contig+K)
            used-=cost[i]
            contig-=profit[i]
            i+=1
        return res

 

posted @ 2021-02-15 10:02  XXXSANS  阅读(67)  评论(0编辑  收藏  举报