Max Consecutive Ones III
Table of Contents + β
Max Consecutive Ones III is a great window question because the window grows and shrinks. You have an array of ones and zeros. You may flip a few zeros to ones. The interviewer wants to see if you can grow a window while you have flips to spare and shrink it when you run out. That balance is the real test here.
π― The Problem
You get an array of 0s and 1s and a number k. Here are the rules.
- You are allowed to flip at most
kzeros into ones. - After flipping, you want the longest run of ones in a row.
- A flip turns one zero into a one. You have at most
kof them. - Return the length of that longest run.
Take the array [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0] and k as 2. You can flip two zeros. The best choice flips the zeros at positions 3 and 4. Then positions 0 through 9 become all ones, a run of length 6. So the answer is 6.
Input: nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2Output: 6
Explanation: Flip the zeros at index 3 and 4.The longest run of ones becomes [1,1,1,1,1,1,1,1] from index 0 to 9, length 6.Here is the idea as a picture. A window covers some stretch of the array. Inside it we count how many zeros we have flipped. The window is valid while that count stays at k or below.
The window has no fixed size here. It stretches as far as the flip budget allows.
π’ Approach 1: Try Every Window (Brute Force)
The idea in one line: try every window and count its zeros from scratch.
The idea:
- Look at every start and every end.
- Count the zeros inside each window.
- The zero count is the flips that window would need.
How it works:
- For each window, if the zero count is
kor less, the window is valid. - Track the longest valid window.
Why it is weak:
- There are about
nstarts andnends. - For each pair you count zeros again.
- That climbs to O(nΒ²) or worse.
- Overlapping windows recount the same zeros.
Here is the brute-force code for that idea:
def longest_ones(nums, k): best = 0 for left in range(len(nums)): zeros = 0 for right in range(left, len(nums)): if nums[right] == 0: zeros += 1 if zeros <= k: best = max(best, right - left + 1) return bestβ‘ Approach 2: A Growing Sliding Window (Best)
The idea in one line: grow the window while you can afford the zeros and shrink it the moment you go over budget.
The idea:
- Use a sliding window with two pointers,
leftandright. - The window is everything between them.
- Keep a count of zeros inside the window. That count is your flip budget.
- The window is valid while the zero count is
kor less.
How it works:
- Move
rightforward one step. If the new number is a zero, add one to the zero count. You spent a flip. - If the zero count goes above
k, the window is invalid. - Then move
leftforward to shrink. If the number leaving was a zero, subtract one. You got a flip back. - Keep shrinking until the count is
kor less again. - After each step the window is valid, so its length is a candidate.
Why it is fast:
- Each pointer only moves forward, at most
nsteps. - No recounting of zeros.
- One clean pass, so O(n).
Here is a dry-run of the window on the example with k equal to 2. Watch how left jumps forward only when the zero count goes over 2.
Steps to Solve
- Set
leftto0and a zero count to0and the best length to0. - Move
rightfrom the start to the end of the array. - If the number at
rightis a zero, add one to the zero count. - While the zero count is greater than
k, shrink. If the number atleftis a zero, subtract one from the count. Then moveleftforward. - The current window length is
right - left + 1. Update the best length if this is larger. - When
rightreaches the end, the best length is the answer.
This Python version uses two index variables left and right and a count of zeros in the window.
def longest_ones(nums, k): left = 0 zeros = 0 best = 0 for right in range(len(nums)): if nums[right] == 0: zeros += 1 # spent a flip while zeros > k: # too many flips if nums[left] == 0: zeros -= 1 # got a flip back left += 1 # shrink from the left best = max(best, right - left + 1) # current valid window return best
nums = [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0]k = 2print(longest_ones(nums, k))The output of the above code will be:
6Let us walk through the Python version line by line and see why each line is there.
The lines left = 0, zeros = 0, best = 0 set up the start. left is the left edge of the window. zeros counts how many zeros are inside the window right now. best holds the longest valid window we have seen.
The loop for right in range(len(nums)) moves the right edge forward one step at a time. right is the new number entering the window.
The lines if nums[right] == 0: zeros += 1 spend a flip. When the entering number is a zero, we would have to flip it. So we add one to the zero count.
The loop while zeros > k checks the budget. If we have used more than k flips, the window is invalid. So we shrink. The line if nums[left] == 0: zeros -= 1 gives a flip back when the number leaving on the left is a zero. The line left += 1 moves the left edge forward, shrinking the window. We keep shrinking until the count is k or less.
The line best = max(best, right - left + 1) measures the current window. The length is right - left + 1. Right after the while loop the window is always valid. So we compare its length with the best so far and keep the larger.
The line return best gives the answer once right has passed the whole array.
β±οΈ Time and Space Complexity
The brute force tries every window, so it is slow and recounts zeros over and over. The sliding window moves each pointer forward only. Each pointer takes at most n steps. So it runs in one pass. That takes the time from O(nΒ²) down to O(n). We keep just a few counters, so the extra space is O(1).
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Brute force (try every window) | O(nΒ²) | O(1) |
| Sliding window with two pointers | O(n) | O(1) |
Tip
In an interview, frame the value of k as a flip budget. You grow the window while you can afford the zeros inside. You shrink the moment you go over budget. Saying it that plainly shows the interviewer you really understand the window pattern.
π§© Key Takeaways
- β Treat k as a flip budget, which is the number of zeros you are allowed to keep inside the window.
- β Grow the window by moving the right pointer, and shrink it by moving the left pointer.
- β The window is valid while the zero count stays at k or below.
- β Right after shrinking, the window is valid, so its length is a candidate for the answer.
- β Each pointer moves forward only, so the whole scan is O(n) time and O(1) space.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What does Max Consecutive Ones III ask you to return?
Why: You return the length of the longest stretch of ones you can make by flipping at most k zeros.
- 2
What does the zero count inside the window represent?
Why: Each zero in the window is a flip you have spent. The window is valid while that count stays at k or below.
- 3
When do you move the left pointer forward?
Why: You shrink from the left only when the zero count exceeds k, to bring the window back to a valid state.
- 4
What is the time and space complexity of the sliding window solution?
Why: Each pointer moves forward at most n times, so it is O(n) time, and only a few counters are kept, so it is O(1) space.