zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    jQuery鼠标事件
    jQuery阻止事件冒泡
    confirm() :带有指定消息和 OK 及取消按钮的对话框
    Win10 Nodejs搭建http-server注意点
    console.dir()可以显示一个对象所有的属性和方法
    git 每次commit之前都要重新配置config
    javascript构造函数类和原型prototype定义的属性和方法的区别
    CSS 超出部分显示省略号
    H5 与 IOS的爱恨情仇(兼容问题)
    ES6之reduce用法
  • 原文地址:https://www.cnblogs.com/xxxsans/p/14403282.html
Copyright © 2011-2022 走看看