Algorithm

Max Consecutive Ones

Arrays & Strings Pattern

Max Consecutive Ones

Given a binary array nums, return the maximum number of consecutive 1s in the array.

CONSTRAINTS
  • 1 <= nums.length <= 10⁵
  • nums[i] is either 0 or 1
EXAMPLE 1
Input: nums = [1,1,0,1,1,1]
Output: 3
Two runs exist: length 2 and length 3. The 0 between them breaks the streak — runs cannot jump over it.
EXAMPLE 2
Input: nums = [1,0,1,1,0,1]
Output: 2
Runs are 1, 2, and 1 long. The longest is 2.
EXAMPLE 3
Input: nums = [0,0,0]
Output: 0
No 1s at all, so no run ever starts. The answer is 0, not -1 or an error.
EXAMPLE 4
Input: nums = [1,1,1,1]
Output: 4
No walls anywhere — the single run spans the whole array.
Does 'consecutive' mean strictly adjacent — a run broken by a single 0 doesn't count as one run?
Correct. A run is an unbroken block of 1s. Even one 0 ends it; counting resumes from zero afterward.
Can I rely on the array containing only 0s and 1s?
Yes, that is guaranteed. No other values will appear.
Should I return the run's length or its position?
Just the length of the longest run. If the array is all 1s, that is simply the array's length; if all 0s, it is 0.

A binary array contains only 0s and 1s, and "consecutive 1s" means an unbroken run of 1s — no gaps allowed. In [1, 1, 0, 1, 1, 1] there are two runs: one of length 2, one of length 3, separated by the 0. The answer is the length of the longest run, here 3. Every 0 acts as a wall: it ends whatever run was in progress, and the next run has to start again from nothing.

One pass with a streak counter

Why is a single walk through the array enough? Because every run has a clear beginning (the start of the array, or the element right after a 0) and a clear end (a 0, or the end of the array). If we walk left to right carrying a counter that means "length of the run of 1s ending at my current position", that counter tells us the full length of every run at the moment the run finishes. On a 1, the run ending here is one longer than the run ending at the previous position — add 1. On a 0, no run ends here at all — reset to 0. A separate variable remembers the longest value the counter ever reached.

You may recognize the shape of this bookkeeping: it is the same "best streak ending here" idea as Kadane's algorithm, in its simplest possible form. There is not even a decision to make — extending a run of 1s can never hurt, so there is no "start fresh instead" choice to weigh.

python
max_ones = current = 0
for x in nums:
    if x == 1:
        current += 1                        # the run ending here grew by one
        max_ones = max(max_ones, current)   # remember the longest run ever seen
    else:
        current = 0                         # a 0 ends any run instantly
return max_ones
Worked Example:nums = [1, 1, 0, 1, 1, 1]
- x = 1: current = 1, max = 1.
- x = 1: current = 2, max = 2.
- x = 0: wall — current resets to 0. Max stays 2.
- x = 1: current = 1. Max stays 2.
- x = 1: current = 2. Max stays 2.
- x = 1: current = 3, max = 3.
- Answer: 3.
Why you cannot do better

Every element must be looked at: any unread position could hold a 0 that splits a promising run, or a 1 that extends one. So O(N) time is optimal, and we used O(1) extra space — two integers. Keep the tool: a counter that grows on success and resets on failure answers any "longest unbroken run of X" question in one pass. And notice what it cannot do: if the question ever becomes "longest run allowing at most one 0 inside", resetting to zero throws away too much — that harder version needs new machinery, and it is worth remembering this boundary when you meet it.

Interactive Strategy Visualization

The Streak Tracker

Strategy: Scan & Remember
1
1
0
1
1
1
0
1
Current Streak
1
Global Record
1
Found a 1! Streak starts at 1. 🔥
ONE-PASS SCAN

We only need to look at each number once. If it's a 1, we add to our streak. If it's a 0, we start over.

REPLACEMENT

Whenever our current streak grows larger than our record, we update the record.

O(N) Single Scan — Optimal