leetcode - 487. Max Consecutive Ones II

本文介绍了解决一个编程问题:给定一个二进制数组,通过最多翻转一个0,找到连续1的最大数量。文章提供了动态规划和滑动窗口两种解决方案,并分析了它们的时间和空间复杂度。
摘要由CSDN通过智能技术生成

Description

Given a binary array nums, return the maximum number of consecutive 1’s in the array if you can flip at most one 0.

Example 1:

Input: nums = [1,0,1,1,0]
Output: 4
Explanation: 
- If we flip the first zero, nums becomes [1,1,1,1,0] and we have 4 consecutive ones.
- If we flip the second zero, nums becomes [1,0,1,1,1] and we have 3 consecutive ones.
The max number of consecutive ones is 4.

Example 2:

Input: nums = [1,0,1,1,0,1]
Output: 4
Explanation: 
- If we flip the first zero, nums becomes [1,1,1,1,0,1] and we have 4 consecutive ones.
- If we flip the second zero, nums becomes [1,0,1,1,1,1] and we have 4 consecutive ones.
The max number of consecutive ones is 4.

Constraints:

1 <= nums.length <= 10^5
nums[i] is either 0 or 1.

Follow up: What if the input numbers come in one by one as an infinite stream? In other words, you can’t store all numbers coming from the stream as it’s too large to hold in memory. Could you solve it efficiently?

Solution

DP

Use dp[i][k] to denote the consecutive 1s if we use i as the ending, and we do k operations. Then the transformation equation is:
d p [ i ] [ k ] = { 1 + max ⁡ ( d p [ i − 1 ] [ : k ] ) ,      if      n u m s [ i ] = = 1 1 + d p [ i − 1 ] [ k − 1 ] ,      if      n u m s [ i ] = = 0 \begin{aligned} dp[i][k] = \begin{cases} 1 + \max(dp[i-1][:k]), &\;\;\text{if} \;\;nums[i]==1 \\ 1 + dp[i-1][k-1], &\;\; \text{if} \;\; nums[i]==0 \end{cases} \end{aligned} dp[i][k]={1+max(dp[i1][:k]),1+dp[i1][k1],ifnums[i]==1ifnums[i]==0

Time complexity: o ( n ∗ k ) o(n*k) o(nk)
Space complexity: o ( n ∗ k ) o(n*k) o(nk)

Sliding window

Use a sliding window, make sure there are no more than one 0 inside the window.

Time complexity: o ( n ) o(n) o(n)
Space complexity: o ( n ) o(n) o(n)

Code

DP

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        dp = [[0] * 2 for _ in range(len(nums))]
        # init
        if nums[0] == 1:
            dp[0][0] = 1
            dp[0][1] = 1
        else:
            dp[0][0] = 0
            dp[0][1] = 1
        # dp
        for i in range(1, len(dp)):
            for k in range(2):
                if nums[i] == 1:
                    dp[i][k] = 1 + max(dp[i - 1][:k + 1])
                else:
                    if k - 1 < 0:
                        dp[i][k] = 0
                    else:
                        dp[i][k] = 1 + dp[i - 1][k - 1]
        res = 0
        for i in range(len(dp)):
            res = max(res, max(dp[i]))
        return res

Sliding window

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        left = 0
        res = 0
        zero_cnt = 0
        for right in range(len(nums)):
            # put item into window
            if nums[right] == 0:
                zero_cnt += 1
            # shrink window if needed
            while zero_cnt > 1:
                if nums[left] == 0:
                    zero_cnt -= 1
                left += 1
            res = max(res, right - left + 1)
        return res
  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值