leetcode - 487. Max Consecutive Ones II

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

你可能感兴趣的:(OJ题目记录,leetcode,算法,职场和发展)