485. Max Consecutive Ones
Problem Description
You are given a binary array nums
that contains only 0s and 1s. Your task is to find the maximum number of consecutive 1s that appear in the array.
For example:
- If
nums = [1, 1, 0, 1, 1, 1]
, the maximum consecutive 1s is 3 (the last three 1s) - If
nums = [1, 0, 1, 1, 0, 1]
, the maximum consecutive 1s is 2 (the two 1s in the middle)
The solution works by maintaining two variables:
cnt
: tracks the current streak of consecutive 1sans
: stores the maximum streak found so far
As we iterate through the array:
- When we encounter a 1, we increment
cnt
and updateans
if the current streak is longer than the maximum found so far - When we encounter a 0, we reset
cnt
to 0 since the consecutive sequence is broken
The time complexity is O(n)
where n
is the length of the array, as we only need one pass through the array. The space complexity is O(1)
since we only use a constant amount of extra space.
Intuition
The key insight is that we need to track consecutive sequences of 1s as we traverse the array. Think of it like counting how many steps you can take forward without interruption - each 1 allows you to continue, but a 0 forces you to start counting from zero again.
We arrive at this approach by recognizing that:
- We only care about unbroken chains of 1s
- A 0 immediately breaks any chain we're currently counting
- We need to remember the longest chain we've seen so far, even after it's been broken
This naturally leads to a two-variable approach:
- One variable (
cnt
) acts as our "current chain counter" that grows when we see a 1 and resets when we see a 0 - Another variable (
ans
) acts as our "record keeper" that remembers the longest chain we've encountered
The beauty of this solution is its simplicity - we don't need to store positions, use sliding windows, or maintain complex data structures. We just need to count and remember. Each time our current count grows, we check if it's a new record. When we hit a 0, we start fresh but keep our record intact.
This pattern of "track current state and update global maximum" is common in array problems where we're looking for optimal consecutive sequences. The same intuition applies to problems like maximum subarray sum or longest substring problems - we maintain local information while tracking the global optimum.
Solution Approach
The solution implements a single-pass algorithm that efficiently tracks consecutive 1s in the array. Let's walk through the implementation step by step:
Variable Initialization:
ans = cnt = 0
We initialize two variables to 0:
ans
: stores the maximum number of consecutive 1s found so farcnt
: tracks the current consecutive 1s count
Main Loop:
for x in nums:
We iterate through each element x
in the array sequentially.
Counting Logic:
if x:
cnt += 1
ans = max(ans, cnt)
else:
cnt = 0
For each element, we check:
- If
x
is 1 (truthy in Python), we:- Increment
cnt
by 1 to extend our current consecutive count - Update
ans
usingmax(ans, cnt)
to keep track of the longest sequence seen so far
- Increment
- If
x
is 0, we:- Reset
cnt
to 0 since the consecutive sequence is broken
- Reset
Return Result:
return ans
After processing all elements, ans
contains the maximum consecutive 1s count.
Example Walkthrough:
For nums = [1, 1, 0, 1, 1, 1]
:
- Index 0:
x=1
,cnt=1
,ans=1
- Index 1:
x=1
,cnt=2
,ans=2
- Index 2:
x=0
,cnt=0
,ans=2
(remains unchanged) - Index 3:
x=1
,cnt=1
,ans=2
(remains unchanged) - Index 4:
x=1
,cnt=2
,ans=2
(remains unchanged) - Index 5:
x=1
,cnt=3
,ans=3
(new maximum) - Return:
3
The algorithm's efficiency comes from processing each element exactly once with constant-time operations, achieving O(n)
time complexity with O(1)
space complexity.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's trace through the algorithm with nums = [1, 0, 1, 1, 0, 1]
:
Initial State:
ans = 0
(maximum consecutive 1s found)cnt = 0
(current consecutive 1s count)
Step-by-step execution:
Index 0: x = 1
- Since
x
is 1, we incrementcnt
:cnt = 0 + 1 = 1
- Update
ans
:ans = max(0, 1) = 1
- State:
cnt = 1, ans = 1
Index 1: x = 0
- Since
x
is 0, we resetcnt
:cnt = 0
ans
remains unchanged at 1- State:
cnt = 0, ans = 1
Index 2: x = 1
- Since
x
is 1, we incrementcnt
:cnt = 0 + 1 = 1
- Update
ans
:ans = max(1, 1) = 1
- State:
cnt = 1, ans = 1
Index 3: x = 1
- Since
x
is 1, we incrementcnt
:cnt = 1 + 1 = 2
- Update
ans
:ans = max(1, 2) = 2
(new maximum!) - State:
cnt = 2, ans = 2
Index 4: x = 0
- Since
x
is 0, we resetcnt
:cnt = 0
ans
remains unchanged at 2- State:
cnt = 0, ans = 2
Index 5: x = 1
- Since
x
is 1, we incrementcnt
:cnt = 0 + 1 = 1
- Update
ans
:ans = max(2, 1) = 2
- State:
cnt = 1, ans = 2
Final Result: Return ans = 2
The maximum consecutive 1s in the array is 2, found at indices 2-3.
Solution Implementation
1class Solution:
2 def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
3 """
4 Find the maximum number of consecutive 1s in a binary array.
5
6 Args:
7 nums: List of binary integers (0s and 1s)
8
9 Returns:
10 Maximum length of consecutive 1s
11 """
12 max_consecutive = 0 # Track the maximum consecutive 1s found so far
13 current_consecutive = 0 # Track the current consecutive 1s count
14
15 # Iterate through each number in the array
16 for num in nums:
17 if num == 1:
18 # If current number is 1, increment the consecutive counter
19 current_consecutive += 1
20 # Update maximum if current consecutive count is larger
21 max_consecutive = max(max_consecutive, current_consecutive)
22 else:
23 # If current number is 0, reset the consecutive counter
24 current_consecutive = 0
25
26 return max_consecutive
27
1class Solution {
2 public int findMaxConsecutiveOnes(int[] nums) {
3 // Variable to store the maximum consecutive ones found so far
4 int maxConsecutiveOnes = 0;
5
6 // Variable to track the current consecutive ones count
7 int currentConsecutiveCount = 0;
8
9 // Iterate through each element in the array
10 for (int num : nums) {
11 if (num == 1) {
12 // If current element is 1, increment the consecutive count
13 currentConsecutiveCount++;
14 // Update the maximum if current consecutive count is larger
15 maxConsecutiveOnes = Math.max(maxConsecutiveOnes, currentConsecutiveCount);
16 } else {
17 // If current element is 0, reset the consecutive count
18 currentConsecutiveCount = 0;
19 }
20 }
21
22 // Return the maximum consecutive ones found
23 return maxConsecutiveOnes;
24 }
25}
26
1class Solution {
2public:
3 int findMaxConsecutiveOnes(vector<int>& nums) {
4 int maxConsecutiveOnes = 0; // Tracks the maximum consecutive 1s found so far
5 int currentCount = 0; // Tracks the current consecutive 1s count
6
7 // Iterate through each element in the array
8 for (int num : nums) {
9 if (num == 1) {
10 // If current element is 1, increment the counter
11 currentCount++;
12 // Update the maximum if current count is larger
13 maxConsecutiveOnes = max(maxConsecutiveOnes, currentCount);
14 } else {
15 // If current element is 0, reset the counter
16 currentCount = 0;
17 }
18 }
19
20 return maxConsecutiveOnes;
21 }
22};
23
1/**
2 * Finds the maximum number of consecutive 1s in a binary array
3 * @param nums - Binary array containing only 0s and 1s
4 * @returns Maximum length of consecutive 1s
5 */
6function findMaxConsecutiveOnes(nums: number[]): number {
7 // Track the maximum consecutive count and current consecutive count
8 let maxConsecutive: number = 0;
9 let currentConsecutive: number = 0;
10
11 // Iterate through each element in the array
12 for (const num of nums) {
13 if (num === 1) {
14 // If current element is 1, increment the consecutive count
15 currentConsecutive++;
16 // Update maximum if current consecutive count is larger
17 maxConsecutive = Math.max(maxConsecutive, currentConsecutive);
18 } else {
19 // If current element is 0, reset the consecutive count
20 currentConsecutive = 0;
21 }
22 }
23
24 return maxConsecutive;
25}
26
Time and Space Complexity
The time complexity is O(n)
, where n
is the length of the array nums
. This is because the algorithm iterates through the array exactly once, performing constant-time operations (comparison, addition, and max operation) for each element.
The space complexity is O(1)
. The algorithm only uses two additional variables (ans
and cnt
) to track the maximum consecutive ones and the current consecutive count, regardless of the input size. No additional data structures that scale with the input are created.
Common Pitfalls
1. Forgetting to Update Maximum Before Resetting
A common mistake is resetting the counter when encountering a 0 without first checking if the current streak should update the maximum. While the provided solution correctly updates ans
immediately when incrementing cnt
, some implementations might try to optimize by only updating at the end of a streak:
Incorrect Approach:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
max_consecutive = 0
current_consecutive = 0
for num in nums:
if num == 1:
current_consecutive += 1
else:
max_consecutive = max(max_consecutive, current_consecutive) # Only updating here
current_consecutive = 0
return max_consecutive # Missing final check!
Issue: This fails when the array ends with consecutive 1s (e.g., [0, 1, 1, 1]
would return 0 instead of 3).
Solution: Always check after the loop ends or update the maximum immediately when incrementing:
# Option 1: Add final check
return max(max_consecutive, current_consecutive)
# Option 2: Update immediately (as in original solution)
if num == 1:
current_consecutive += 1
max_consecutive = max(max_consecutive, current_consecutive)
2. Using Wrong Variable Names Leading to Confusion
When using short variable names like cnt
and ans
, it's easy to mix them up, especially in longer functions:
Error-Prone:
ans = cnt = 0
for x in nums:
if x:
ans += 1 # Accidentally incrementing wrong variable
cnt = max(ans, cnt) # Variables swapped
Solution: Use descriptive variable names:
max_count = current_count = 0
for num in nums:
if num == 1:
current_count += 1
max_count = max(max_count, current_count)
3. Incorrect Handling of Edge Cases
Not considering edge cases can lead to runtime errors:
Potential Issues:
- Empty array:
nums = []
- Single element:
nums = [1]
ornums = [0]
- All zeros:
nums = [0, 0, 0]
- All ones:
nums = [1, 1, 1]
Solution: The algorithm naturally handles these cases, but always verify:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
if not nums: # Explicit empty check if needed
return 0
max_consecutive = current_consecutive = 0
# Rest of implementation...
4. Using Unnecessary Space with Additional Data Structures
Some might be tempted to store all consecutive sequences first:
Space-Inefficient:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
sequences = [] # Unnecessary list
current = 0
for num in nums:
if num == 1:
current += 1
else:
if current > 0:
sequences.append(current)
current = 0
if current > 0:
sequences.append(current)
return max(sequences) if sequences else 0
Solution: Maintain only the maximum value during iteration (as in the original solution) to achieve O(1) space complexity.
Which of the following is a good use case for backtracking?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!