Max Consecutive Ones II
Medium · Sliding Window · Explanation and code example
Sliding Window
How it works
Instead of restarting from every position, we can use a sliding window that grows and shrinks dynamically. The key insight is that we only need to shrink the window when we have more than one zero inside it. By maintaining a count of zeros in the current window, we expand by moving the right pointer and contract by moving the left pointer whenever the window becomes invalid. This way, each element is visited at most twice, making the solution linear.
Steps
- Initialize two pointers
leftandrightat0, along withnumZeroesto track zeros in the window. - Expand the window by moving
right:- If the element at
rightis0, incrementnumZeroes.
- If the element at
- While
numZeroesequals2(window is invalid):- If the element at
leftis0, decrementnumZeroes. - Move
leftforward to shrink the window.
- If the element at
- Update
longestSequencewith the current window size (right - left + 1). - Continue until
rightreaches the end, then returnlongestSequence.
Complexity
- Time complexity:
O(n) - Space complexity:
O(1)constant space used
Where
nis the length of the input arraynums.
Things to watch for
Off-by-One Errors in Window Size Calculation
When calculating the window size, remember that for indices left and right, the window size is right - left + 1, not right - left. Forgetting the +1 results in consistently underreporting the maximum consecutive ones by one.
Incorrectly Handling the Zero Count Threshold
The window becomes invalid when numZeroes reaches 2 (since we can only flip one zero). A common mistake is using numZeroes > 1 in some places and numZeroes == 2 in others, leading to inconsistent behavior. Be consistent with your threshold check and ensure you shrink the window only when you have exceeded the allowed number of zeros.
Not Updating the Maximum Before Shrinking
Make sure to update the longest sequence answer at the right time. If you shrink the window first and then try to update the maximum, you might miss the optimal window size. In the sliding window approach, update the result after ensuring the window is valid, not before handling the invalid case.
Python code example
from typing import List
class Solution:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
longest_sequence = 0
left, right = 0, 0
num_zeroes = 0
while right < len(nums): # While our window is in bounds
if nums[right] == 0: # Increase num_zeroes if the rightmost element is 0
num_zeroes += 1
while num_zeroes == 2: # If our window is invalid, contract our window
if nums[left] == 0:
num_zeroes -= 1
left += 1
longest_sequence = max(longest_sequence, right - left + 1) # Update our longest sequence answer
right += 1 # Expand our window
return longest_sequence
C++ code example
class Solution {
public:
int findMaxConsecutiveOnes(vector<int>& nums) {
int longestSequence = 0;
int left = 0;
int right = 0;
int numZeroes = 0;
// While our window is in bounds
while (right < nums.size()) {
// Increase numZeroes if the rightmost element is 0
if (nums[right] == 0) {
numZeroes++;
}
//If our window is invalid, contract our window
while (numZeroes == 2) {
if (nums[left] == 0) {
numZeroes--;
}
left++;
}
// Update our longest sequence answer
longestSequence = max(longestSequence, right - left + 1);
// Expand our window
right++;
}
return longestSequence;
}
};
Source and license
Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.