Before attempting this problem, you should be comfortable with:
The simplest approach is to try every possible starting position and extend the window as far as we can while allowing at most one zero to be flipped. For each starting index, we scan forward and count zeros. As long as we have seen at most one zero, the current window is valid. Once we encounter a second zero, we stop extending and record the maximum length found so far. This guarantees we consider all possible substrings but results in checking many overlapping ranges.
longestSequence to track the maximum valid window length.left, iterate through the array with right:1, stop expanding this window.longestSequence with the current window size.longestSequence.class Solution:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
longest_sequence = 0
for left in range(len(nums)):
num_zeroes = 0
for right in range(left, len(nums)): # Check every consecutive sequence
if num_zeroes == 2:
break
if nums[right] == 0: # Count how many 0's
num_zeroes += 1
if num_zeroes <= 1: # Update answer if it's valid
longest_sequence = max(longest_sequence, right - left + 1)
return longest_sequenceWhere is the length of the input array
nums.
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.
left and right at 0, along with numZeroes to track zeros in the window.right:right is 0, increment numZeroes.numZeroes equals 2 (window is invalid):left is 0, decrement numZeroes.left forward to shrink the window.longestSequence with the current window size (right - left + 1).right reaches the end, then return longestSequence.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_sequenceWhere is the length of the input array
nums.
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.
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.
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.