Contiguous Array
Description
Given a binary array nums, return the maximum length of a contiguous subarray with an equal number of 0 and 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] are the longest with equal 0s and 1s. The entire array has 2 zeros and 1 one, so it doesn't qualify.
Example 3:
Input: nums = [0,1,1,1,1,1,0,0,0]
Output: 6
Explanation: The subarray [1,1,1,0,0,0] (indices 3-8) has 3 ones and 3 zeros.
Constraints
1 <= nums.length <= 10^5nums[i] is either 0 or 1
Complexity
Show Complexity
- Time:
O(n) - Space:
O(n)
Hints
Show Hints
- Pattern
- Prefix sum with hash map
- Approach
- Replace 0 with -1. Use prefix sum - when same prefix appears twice, the subarray between has equal 0s and 1s (sum = 0). Store first occurrence of each prefix in a hash map.
- Complexity
- Transform 0 to -1, then find longest subarray with sum = 0
Notes
Show Notes
Contiguous Array
Problem
Find the maximum length of a contiguous subarray with an equal number of 0s and 1s.
Approach: Prefix Sum with Hash Map
Key Insight
Transform the problem:
- Treat
0as-1 - Treat
1as+1
Now “equal 0s and 1s” becomes “subarray with sum = 0”.
What is Prefix Sum Here?
prefix[i] = (count of 1s) - (count of 0s) from index 0 to i
nums: [0, 0, 0, 1, 1, 0, 1]
as +/-: -1 -1 -1 +1 +1 -1 +1
prefix: 0 -1 -2 -3 -2 -1 -2 -1
index: -1 0 1 2 3 4 5 6
↑
"before array"
Why prefix[-1] = 0?
Before processing any elements:
- Count of 1s = 0
- Count of 0s = 0
- Prefix = 0 - 0 = 0
This handles subarrays that start from index 0.
The Core Insight: Same Prefix = Valid Subarray
If prefix[i] == prefix[j] (where j > i), then:
prefix[j] - prefix[i] = 0
(1s from i to j) - (0s from i to j) = 0
(1s from i to j) = (0s from i to j) ← EQUAL!
Example from the trace above:
prefix: 0 -1 -2 -3 -2 -1 -2 -1
index: -1 0 1 2 3 4 5 6
↑ ↑
prefix=-1 prefix=-1
Prefix is -1 at index 0 and again at index 4.
Subarray from index 1 to 4 = [0, 0, 1, 1] → 2 zeros, 2 ones!
Length = 4 - 0 = 4
Why Store First Occurrence Only?
We want the longest subarray, so we need the earliest index for each prefix.
If prefix = -1 appears at indices 0, 4, 6:
Using first (index 0):
- At index 4: length = 4 - 0 = 4
- At index 6: length = 6 - 0 = 6 ← longest!
If we overwrote with latest:
- At index 6: length = 6 - 4 = 2 ← wrong!
Step-by-Step Trace
nums = [0, 1, 0]
Setup: map = {0: -1} ← prefix 0 first seen at index -1
i = 0, nums[0] = 0
curr = 0 + (-1) = -1
is -1 in map? NO → store it
map = {0: -1, -1: 0}
i = 1, nums[1] = 1
curr = -1 + 1 = 0
is 0 in map? YES, at index -1
length = 1 - (-1) = 2 ← [0,1] has equal 0s and 1s!
max_len = 2
i = 2, nums[2] = 0
curr = 0 + (-1) = -1
is -1 in map? YES, at index 0
length = 2 - 0 = 2 ← [1,0] has equal 0s and 1s!
max_len = 2
Answer: 2
Solution
def solution(nums: list[int]) -> int:
prefix_index = {0: -1} # prefix value → first index
curr = 0
max_len = 0
for i, num in enumerate(nums):
curr += 1 if num else -1
if curr in prefix_index:
max_len = max(max_len, i - prefix_index[curr])
else:
prefix_index[curr] = i
return max_len
Complexity
- Time: O(n) - single pass through the array
- Space: O(n) - hash map stores at most n+1 distinct prefix values
Comparison: Count vs Length Problems
| Goal | Map stores | When prefix repeats |
|---|---|---|
| Count subarrays | count of occurrences | result += count |
| Max length | first index | max_len = max(max_len, i - first_index) |
Map Initialization
Always ask: “What prefix exists before the array starts?”
- Count problem:
{0: 1}→ prefix 0 has occurred 1 time - Length problem:
{0: -1}→ prefix 0 first appeared at index -1
Solutions
Show PY Solution
from collections import defaultdict
def solution(nums: list[int]) -> int:
if len(nums) == 1:
return 0
m = defaultdict(int)
m[0] = -1
count = 0
curr = 0
for i in range(len(nums)):
if nums[i] == 0:
curr -= 1
else:
curr += 1
if curr not in m:
m[curr] = i
count = max(count, i - m[curr])
return count
# count = 0
# for i in range(len(nums)):
# if nums[i] == 0:
# curr = -1
# else:
# curr = 1
# j = i + 1
# for j in range(i + 1, len(nums)):
# if nums[j] == 0:
# curr -= 1
# else:
# curr += 1
# if curr == 0:
# count = max(count, j - i + 1)
#
# return count
#