这是我参与更文挑战的第3天,活动详情查看更文挑战
问题描述
Given a binary array nums, return the maximum length of a contiguous subarray with an equal number of 0 and 1.
给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。
Example 1:
Input: nums = [0,1]
Output: 2
Explanation: [0, 1] is the longest contiguous subarray with an equal number of 0 and 1.
Example 2:
Input: nums = [0,1,0]
Output: 2
Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1.
Constraints:
-
nums.length nums[i]is either or
提示:
-
nums.length nums[i]不是 就是
解题思路
根据题意,可以发现的关键性规律是:如果答案非 0,那么子数组长度必然为偶数,且长度至少为 2
使用前缀和与哈希表解题
具体的,我们在预处理前缀和时,将 nums[i] 为 0 的值当做 −1 处理。
从而将问题转化为:如何求得最长一段区间和为 0 的子数组。
同时使用「哈希表」来记录「某个前缀和出现的最小下标」是多少。
再结合「如果答案非 0,子数组长度至少为 2」的特性,我们让循环从 2开始,并在循环开始前往「哈希表」存入哨兵,从而实现不需要处理边界问题。
代码
Python 代码
class Solution:
def findMaxLength(self, nums: List[int]) -> int:
# 记录数组长度
n = len(nums)
# 初始化前缀和列表
sum_list = [0] * (n + 1)
for i in range(1, n + 1):
# 记录前缀和
sum_list[i] = sum_list[i - 1] + (1 if nums[i - 1] == 1 else -1)
ans = 0
# 使用哈希表(字典)保存
hashmap = {0: 0}
for i in range(2, n + 1):
if sum_list[i - 2] not in hashmap:
hashmap[sum_list[i - 2]] = i - 2
if sum_list[i] in hashmap:
ans = max(ans, i - hashmap[sum_list[i]])
return ans
C++代码
class Solution:
def findMaxLength(self, nums: List[int]) -> int:
# 记录数组长度
n = len(nums)
# 初始化前缀和列表
sum_list = [0] * (n + 1)
for i in range(1, n + 1):
# 记录前缀和
sum_list[i] = sum_list[i - 1] + (1 if nums[i - 1] == 1 else -1)
ans = 0
# 使用哈希表(字典)保存
hashmap = {0: 0}
for i in range(2, n + 1):
if sum_list[i - 2] not in hashmap:
hashmap[sum_list[i - 2]] = i - 2
if sum_list[i] in hashmap:
ans = max(ans, i - hashmap[sum_list[i]])
return ans