在问 · 算法题解

525. 连续数组

题目描述

输入只含 0 和 1 的数组 nums。

在所有 0 的个数与 1 的个数相等的连续子数组中,找出最长的一个,返回它的长度。不存在这样的子数组时返回 0。

示例 1
输入:nums = [0,1]
输出:2

解释:整个数组含一个 0 和一个 1。

示例 2
输入:nums = [0,1,0]
输出:2

解释:[0,1] 或 [1,0] 都满足,长度为 2。

示例 3
输入:nums = [0,1,1,1,1,1,0,0,0]
输出:6

解释:[1,1,1,0,0,0] 含三个 0 和三个 1,长度为 6。

数据范围

  • 1 <= nums.length <= 10^5
  • nums[i] 只会是 0 或 1。

解题思路

把 0 看成 -1,“0 和 1 一样多”就变成“子数组和为 0”。用 bal 表示前缀中 1 的个数减 0 的个数,若两个位置的 bal 相同,它们之间的子数组就是平衡的。用哈希表记录每个 bal 最早出现的下标(空前缀 bal=0 记在 -1),每次遇到已出现的 bal 就用 i - first[bal] 更新最长长度。

为什么正确

first[b] 是已扫描前缀中 bal 等于 b 的最小下标;best 是以已扫描位置结尾的最长平衡子数组长度。

复杂度分析

时间 O(n),空间 O(n)。

易错点

已经出现过的 bal 不要用新下标覆盖:要的是最长子数组,所以左端点越早越好。忘记放入 {0: -1} 会漏掉从下标 0 开始的子数组。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def findMaxLength(self, nums: List[int]) -> int:
        first = {0: -1}
        bal = best = 0
        for i, x in enumerate(nums):
            bal += 1 if x == 1 else -1
            if bal in first:
                best = max(best, i - first[bal])
            else:
                first[bal] = i
        return best

载入编辑器,自己跑一遍 →

哈希表 专题的其他题目

查看 哈希表 全部题目 →