跳至主要內容

0487. 最大连续1的个数 II

ITCharge大约 2 分钟

0487. 最大连续1的个数 IIopen in new window

  • 标签:数组、动态规划、滑动窗口
  • 难度:中等

题目链接

题目大意

描述:给定一个二进制数组 numsnums,可以最多将 1100 翻转为 11

要求:如果最多可以翻转一个 00,则返回数组中连续 11 的最大个数。

说明

  • 1 <= nums.length <= 105
    nums[i] 不是 0 就是 1.

示例

  • 示例 1:
输入:nums = [1,0,1,1,0]
输出:4
解释:翻转第一个 0 可以得到最长的连续 1。当翻转以后,最大连续 1 的个数为 4
  • 示例 2:
输入:nums = [1,0,1,1,0,1]
输出:4

解题思路

思路 1:滑动窗口

暴力做法是尝试将每个位置的 00 分别变为 11,然后统计最大连续 11 的个数。但这样复杂度就太高了。

我们可以使用滑动窗口来解决问题。保证滑动窗口内最多有 1100。具体做法如下:

设定两个指针:leftleftrightright,分别指向滑动窗口的左右边界,保证滑动窗口内最多有 1100。使用 zerocountzero\underline{}count 统计窗口内 11 的个数。使用 ansans 记录答案。

  • 一开始,leftleftrightright 都指向 00
  • 如果 nums[right]==0nums[right] == 0,则窗口内 11 的个数加 11
  • 如果该窗口中 11 的个数多于 11 个,即 zerocount>1zero\underline{}count > 1,则不断右移 leftleft,缩小滑动窗口长度,并更新窗口中 11 的个数,直到 zerocount1zero\underline{}count \le 1
  • 维护更新最大连续 11 的个数。然后右移 rightright,直到 rightlen(nums)right \ge len(nums) 结束。
  • 输出最大连续 11 的个数。

思路 1:代码

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        left, right = 0, 0
        ans = 0
        zero_count = 0

        while right < len(nums):
            if nums[right] == 0:
                zero_count += 1
            while zero_count > 1:
                if nums[left] == 0:
                    zero_count -= 1
                left += 1
            ans = max(ans, right - left + 1)
            right += 1

        return ans

思路 1:复杂度分析

  • 时间复杂度O(n)O(n),其中 nn 为数组 numsnums 的长度。
  • 空间复杂度O(1)O(1)