Given a binary array and a budget of k zero-to-one flips, find the longest contiguous run of 1s you can produce. It is a variable-size sliding window that stays valid while it contains at most k zeros.
You are given an array nums of only 0s and 1s and an integer k. You may flip at most k zeros to ones. Return the length of the longest contiguous subarray that is all 1s after the flips.
Example: nums=[1,1,1,0,0,0,1,1,1,1,0], k=2. Flip the two zeros at indices 4 and 5, giving 1,1,1,1,1,1 across indices 4–9 (length 6). Answer: 6.
kzeros" means a subarray is achievable iff it contains at most k zeros— every zero inside is one flip you can afford. So track a single number: how many 0s are in the current window. Grow the window on the right; whenever the zero count exceeds k, shrink from the left until it is valid again. The answer is the largest valid window seen.L = 0, zeros = 0, best = 0.nums[R] === 0, increment zeros— a new zero just entered the window and would cost a flip.zeros > k, advance L; if the element leaving was a 0, decrement zeros. Stop once the window again holds ≤ k zeros.best = Math.max(best, R - L + 1)— the current window is guaranteed valid here.best.windowLen − maxFreq) and Longest Subarray of 1s After Deleting One Element (LC 1493, where k = 1and you subtract 1 at the end). Whenever you see "flip / delete / replace at most k," reach for this window.R advances n times and L advances at most n times total across the whole run, so the inner whileis amortized O(1) — total work is O(2n) = O(n). Only three integer counters are kept, so space is O(1).
R rightward, counting 0s inside the window. The window stays valid while zeros ≤ k (every 0 can be flipped to a 1).1function longestOnes(nums: number[], k: number): number {2▶ let L = 0;3▶ let zeros = 0;4▶ let best = 0;56 for (let R = 0; R < nums.length; R++) {7 if (nums[R] === 0) zeros++; // a 0 entered the window89 while (zeros > k) { // too many 0s to flip10 if (nums[L] === 0) zeros--; // a 0 is leaving on the left11 L++;12 }1314 best = Math.max(best, R - L + 1); // window now has <= k zeros15 }1617 return best;18}
function longestOnes(nums: number[], k: number): number {
let L = 0;
let zeros = 0;
let best = 0;
for (let R = 0; R < nums.length; R++) {
if (nums[R] === 0) zeros++; // a 0 entered the window
while (zeros > k) { // too many 0s to flip
if (nums[L] === 0) zeros--; // a 0 is leaving on the left
L++;
}
best = Math.max(best, R - L + 1); // window now has <= k zeros
}
return best;
}L is the window's left edge, zeros counts how many 0s are currently inside it, and best remembers the longest valid window seen so far.0, it costs a flip, so bump zeros.zeros now exceeds k, the window needs more flips than we have. Advance L; when the element that leaves is a 0, that flip is freed, so decrement zeros. The loop runs until the window is valid again.R - L + 1 is achievable. Update best if it is the longest yet.R moves forward n times and L moves forward at most n times in total, so each index is visited at most twice. O(1) space: just the three counters L, zeros, and best.bestL = L whenever best updates and return nums.slice(bestL, bestL + best).windowLen − maxFreq, here it is simply the number of zeros. Same expand/shrink loop.k = 1, then subtract one from the answer because a deletion (not a flip) is required.0 raises zeros by one, so the while removes at most one element per step; L never overtakes R.function longestOnes(nums: number[], k: number): number {
let L = 0;
let zeros = 0;
let best = 0;
for (let R = 0; R < nums.length; R++) {
if (nums[R] === 0) zeros++; // a 0 entered the window
while (zeros > k) { // too many 0s to flip
if (nums[L] === 0) zeros--; // a 0 is leaving on the left
L++;
}
best = Math.max(best, R - L + 1); // window now has <= k zeros
}
return best;
}R moves forward n times and L moves forward at most n times in total, so each index is visited at most twice. O(1) space: just the three counters L, zeros, and best.For each start index, extend to the right counting zeros; the subarray is achievable while its zero count stays ≤ k.
function longestOnes(nums: number[], k: number): number {
let best = 0;
for (let i = 0; i < nums.length; i++) {
let zeros = 0;
for (let j = i; j < nums.length; j++) {
if (nums[j] === 0) zeros++;
if (zeros > k) break; // can't flip this many
best = Math.max(best, j - i + 1);
}
}
return best;
}O(n²). The sliding window keeps one window that only grows on the right and shrinks on the left, collapsing the work into a single O(n) pass.A subtle variant: replace the while with an ifso the window slides as a unit and never shrinks — the final R - L is the answer.
function longestOnes(nums: number[], k: number): number {
let L = 0;
let zeros = 0;
for (let R = 0; R < nums.length; R++) {
if (nums[R] === 0) zeros++;
if (zeros > k) { // slide, don't shrink
if (nums[L] === 0) zeros--;
L++;
}
}
return nums.length - L; // window width never shrank
}R - L + 1 is monotonically non-decreasing, so the final width n - L equals the best ever seen. Same O(n), slightly slicker but less obvious than the explicit while + best version.| "flip at most k zeros / bits to 1" | sliding window, valid while zeros ≤ k |
| binary array + "longest run of 1s" | count zeros in window, shrink when over budget |
| "at most k bad elements in a subarray" | variable-size window, shrink-left invariant |
| "delete one element to extend a run" | same window with k = 1, subtract 1 from the answer |
let L = 0, zeros = 0, best = 0;
for (let R = 0; R < nums.length; R++) {
if (nums[R] === 0) zeros++;
while (zeros > k) {
if (nums[L] === 0) zeros--;
L++;
}
best = Math.max(best, R - L + 1);
}
return best;kzeros — each zero is a flip you can afford.nums=[1,1,1,0,0,0,1,1,1,1,0], k=2, what does the algorithm return?while (zeros > k) loop, when do you decrement zeros?k = 0?