跳转至

487. 最大连续1的个数 II 🔒

题目描述

给定一个二进制数组 nums ,如果最多可以翻转一个 0 ,则返回数组中连续 1 的最大个数。

 

示例 1:

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

示例 2:

输入:nums = [1,0,1,1,0,1]
输出:4

 

提示:

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

 

进阶:如果输入的数字是作为 无限流 逐个输入如何处理?换句话说,内存不能存储下所有从流中输入的数字。您可以有效地解决吗?

解法

方法一:滑动窗口

思考

最多把一个 \(0\) 当成 \(1\),求最长连续 \(1\)。这是「窗口内 \(0\) 的个数不超过 \(1\)」的最长窗口。

右端扩张,用 \(x\oplus 1\) 统计窗口内的 \(0\);超过一个则左端右移一格。只需最大长度,左端每次只移一步,答案为 \(n-l\)

与「最多替换 \(k\) 次」同类:窗口单调变长,不必把左端一次移到底。

我们可以遍历数组,用一个变量 \(\textit{cnt}\) 记录当前窗口中 0 的个数,当 \(\textit{cnt} > 1\) 时,我们将窗口的左边界右移一位。

遍历结束后,窗口的长度即为最大连续 1 的个数。

注意,在上述过程中,我们不需要循环将窗口的左边界右移,而是直接将左边界右移一位,这是因为,题目求的是最大连续 1 的个数,因此,窗口的长度只会增加,不会减少,所以我们不需要循环右移左边界。

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

1
2
3
4
5
6
7
8
9
class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        l = cnt = 0
        for x in nums:
            cnt += x ^ 1
            if cnt > 1:
                cnt -= nums[l] ^ 1
                l += 1
        return len(nums) - l
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int l = 0, cnt = 0;
        for (int x : nums) {
            cnt += x ^ 1;
            if (cnt > 1) {
                cnt -= nums[l++] ^ 1;
            }
        }
        return nums.length - l;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
        int l = 0, cnt = 0;
        for (int x : nums) {
            cnt += x ^ 1;
            if (cnt > 1) {
                cnt -= nums[l++] ^ 1;
            }
        }
        return nums.size() - l;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func findMaxConsecutiveOnes(nums []int) int {
    l, cnt := 0, 0
    for _, x := range nums {
        cnt += x ^ 1
        if cnt > 1 {
            cnt -= nums[l] ^ 1
            l++
        }
    }
    return len(nums) - l
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function findMaxConsecutiveOnes(nums: number[]): number {
    let [l, cnt] = [0, 0];
    for (const x of nums) {
        cnt += x ^ 1;
        if (cnt > 1) {
            cnt -= nums[l++] ^ 1;
        }
    }
    return nums.length - l;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
/**
 * @param {number[]} nums
 * @return {number}
 */
var findMaxConsecutiveOnes = function (nums) {
    let [l, cnt] = [0, 0];
    for (const x of nums) {
        cnt += x ^ 1;
        if (cnt > 1) {
            cnt -= nums[l++] ^ 1;
        }
    }
    return nums.length - l;
};

评论