The Contiguous Array problem on LeetCode asks you to find the length of the longest contiguous subarray within a binary array (an array containing only 0
s and 1
s) that contains an equal number of 0
s and 1
s.
nums
consisting of only 0
s and 1
s.0
s and 1
s.
Example:
Input: nums = [0,1,0]
Output: 2
Explanation: The contiguous subarray [0,1]
or [1,0]
has equal numbers of 0
s and 1
s.
At first glance, you might think about checking every possible subarray and counting the number of 0
s and 1
s in each. However, this would be very inefficient for large arrays, as there are many possible subarrays.
Instead, we look for a way to quickly determine if a subarray has equal numbers of 0
s and 1
s. One key insight is that if we treat 0
as -1
and 1
as +1
, then the problem reduces to finding the longest subarray whose sum is zero.
This is similar to the classic "subarray sum equals k" problem, and suggests we can use a hash map to store the first occurrence of each cumulative sum. This allows us to efficiently find the longest subarray where the number of 0
s and 1
s are equal.
0
in the array with -1
.
0
means equal numbers of 0
s and 1
s.count
to keep track of the running sum as you iterate through the array.
count_to_index
) to store the earliest index at which each count
value has occurred.
count
value appears again at a later index, it means the subarray between those indices has a net sum of 0
(i.e., equal numbers of 0
s and 1
s).count
has been seen before, calculate the length of the subarray from the previous index to the current index and update the maximum length.count
in the hash map.
We use a hash map because it allows us to look up whether we've seen a particular count
value before in constant time, which is crucial for efficiency.
Let's consider the input nums = [0, 1, 0, 1, 1, 0, 0]
.
0
with -1
: [-1, 1, -1, 1, 1, -1, -1]
count = 0
and count_to_index = {0: -1}
(to handle the case where the subarray starts at index 0).count
and checking if it has been seen before:
-1: 0
.1: 4
.0
s and 1
s.O(n^2)
because there are O(n^2)
subarrays.O(1)
(ignoring input and output).O(n)
because we iterate through the array once and hash map operations are constant time.O(n)
for the hash map (in the worst case, all prefix sums are unique).
The key to solving the Contiguous Array problem efficiently is to recognize that by mapping 0
s to -1
s, the problem reduces to finding the longest subarray with sum zero. Using a hash map to store the first occurrence of each running sum allows us to check in constant time whether a subarray with equal numbers of 0
s and 1
s exists up to any index. This approach turns a brute-force O(n^2)
problem into a clean and efficient O(n)
solution.
class Solution:
def findMaxLength(self, nums):
count_to_index = {0: -1}
count = 0
max_length = 0
for i, num in enumerate(nums):
count += 1 if num == 1 else -1
if count in count_to_index:
max_length = max(max_length, i - count_to_index[count])
else:
count_to_index[count] = i
return max_length
class Solution {
public:
int findMaxLength(vector<int>& nums) {
unordered_map<int, int> count_to_index;
count_to_index[0] = -1;
int count = 0, max_length = 0;
for (int i = 0; i < nums.size(); ++i) {
count += (nums[i] == 1) ? 1 : -1;
if (count_to_index.find(count) != count_to_index.end()) {
max_length = max(max_length, i - count_to_index[count]);
} else {
count_to_index[count] = i;
}
}
return max_length;
}
};
class Solution {
public int findMaxLength(int[] nums) {
Map<Integer, Integer> countToIndex = new HashMap<>();
countToIndex.put(0, -1);
int count = 0, maxLength = 0;
for (int i = 0; i < nums.length; i++) {
count += (nums[i] == 1) ? 1 : -1;
if (countToIndex.containsKey(count)) {
maxLength = Math.max(maxLength, i - countToIndex.get(count));
} else {
countToIndex.put(count, i);
}
}
return maxLength;
}
}
var findMaxLength = function(nums) {
const countToIndex = new Map();
countToIndex.set(0, -1);
let count = 0, maxLength = 0;
for (let i = 0; i < nums.length; i++) {
count += nums[i] === 1 ? 1 : -1;
if (countToIndex.has(count)) {
maxLength = Math.max(maxLength, i - countToIndex.get(count));
} else {
countToIndex.set(count, i);
}
}
return maxLength;
};