Longest Subarray of Ones After Deleting One Element — At-Most-One-Zero Window [LC 1493, Google]

Sanjeev SharmaSanjeev Sharma
8 min read

Advertisement

Problem Statement

LeetCode 1493 — Longest Subarray of 1s After Deleting One Element · Difficulty: Medium

Given a binary array nums, you should delete one element from it. Return the size of the longest non-empty subarray containing only 1s in the resulting array. Return 0 if there is no such subarray.

Constraints:

  • 1 <= nums.length <= 10^5
  • nums[i] is either 0 or 1

Example 1:

Input:  nums = [1, 1, 0, 1]
Output: 3
Explanation: Delete the 0 at index 2 → [1, 1, 1]. Longest subarray of 1s = 3.

Example 2:

Input:  nums = [0, 1, 1, 1, 0, 1, 1, 0, 1]
Output: 5
Explanation: Delete a 0 to get a subarray of 5 consecutive 1s (indices 1-5).

Example 3:

Input:  nums = [1, 1, 1]
Output: 2
Explanation: You must delete one element. All elements are 1, so delete any one.
             Longest remaining subarray of 1s = 2.

Why This Problem Matters

LC 1493 is a clean medium problem that tests a specific reframing skill: converting "delete exactly one element and maximize ones" into "find the longest window with at most one zero." The result is window_length - 1 (subtracting the one mandatory deletion).

Google and Amazon use this problem to test whether candidates recognize the equivalence between the delete-one constraint and the at-most-k-zeros sliding window. It is also a gentle warm-up for LC 1004 (Max Consecutive Ones III), which generalizes to "at most k zeros."

The all-ones edge case (Example 3) catches candidates off-guard: you must delete one element even when all are 1s, so the answer is n - 1, not n. The formula right - left (window size minus 1) handles this automatically.

The Core Insight

Reframe: The longest subarray of 1s after deleting exactly one element equals the longest window containing at most one zero, minus 1 (for the deleted element). That minus-1 is baked into the formula right - left (window size right - left + 1 minus 1).

Shrinkable window with zero budget:

  • Expand right: if nums[right] == 0, increment zeros.
  • Shrink left while zeros > 1: if nums[left] == 0, decrement zeros; advance left.
  • After shrinking, the window [left, right] has at most one zero. The subarray of 1s obtained by deleting that zero has length right - left (window size minus 1).
  • Track the maximum right - left across all positions.

Visual Dry Run

Input: nums = [0, 1, 1, 1, 0, 1, 1, 0, 1]

rightvalzerosleftwindow [left,right]right - left
0010[0,0]="0"0
1110[0,1]="01"1
2110[0,2]="011"2
3110[0,3]="0111"3
402→ shrink: nums[0]=0 → zeros=1, left=1[1,4]="1110"3
5111[1,5]="11101"4
6111[1,6]="111011"5
702→ shrink: nums[1]=1, left=2; nums[2]=1, left=3; nums[3]=1, left=4; nums[4]=0 → zeros=1, left=5[5,7]="110"2
8115[5,8]="1101"3

Maximum right - left = 5

Common Mistakes

  1. Returning right - left + 1 instead of right - left. The problem asks for the length of the subarray after the deletion — the window of length right - left + 1 contains one zero; deleting it gives a subarray of length right - left. Always subtract 1.

  2. Forgetting the all-ones edge case. When all elements are 1, zeros is always 0, and right - left at the final position gives n - 1 — correct, because you must delete one element. No special case needed.

  3. Shrinking with while nums[left] == 1: left++ instead of tracking zeros. This is wrong: it can advance left past a zero that should be kept. Always track zeros explicitly.

  4. Not advancing left far enough. When zeros == 2, you need to shrink until zeros <= 1 — which requires finding and removing one of the two zeros. The while zeros > 1 loop handles this correctly.

  5. Initializing ans = -1 and returning 0 when no ones exist. If all elements are 0, every window has zeros > 0 after just one element, so after any shrink, right - left is 0. The maximum remains 0, which is the correct answer.

Solutions

Python

def longestSubarray(nums: list[int]) -> int:
    left = 0
    zeros = 0          # count of zeros in current window
    ans = 0            # longest subarray of 1s after one deletion
 
    for right in range(len(nums)):
        if nums[right] == 0:
            zeros += 1         # include a zero in the window
 
        # Shrink from left while window has more than one zero
        while zeros > 1:
            if nums[left] == 0:
                zeros -= 1     # remove a zero from the window
            left += 1          # advance left pointer
 
        # Window [left, right] has at most one zero.
        # Deleting that zero gives a subarray of length (right - left + 1) - 1 = right - left.
        ans = max(ans, right - left)
 
    return ans

JavaScript

function longestSubarray(nums) {
    let left = 0;
    let zeros = 0;       // count of zeros in the current window
    let ans = 0;
 
    for (let right = 0; right < nums.length; right++) {
        if (nums[right] === 0) {
            zeros++;              // expand: include a zero
        }
 
        // Shrink while more than one zero is in the window
        while (zeros > 1) {
            if (nums[left] === 0) {
                zeros--;          // remove a zero from the left
            }
            left++;               // advance left
        }
 
        // Window length is (right - left + 1); after mandatory deletion: right - left
        ans = Math.max(ans, right - left);
    }
 
    return ans;
}

Complexity Analysis

ApproachTimeSpaceNotes
Brute force (all subarrays)O(n²)O(1)TLE for n = 10^5
Shrinkable window (this)O(n)O(1)Each pointer moves forward at most n times

right advances from 0 to n-1 (n steps). left only moves forward, advancing at most n times total across all iterations of the while loop. Total: O(n) time, O(1) space.

Follow-up Questions

  1. LC 1004 — Max Consecutive Ones III (at most k flips): Generalize the budget from 1 to k. Replace zeros > 1 with zeros > k. The rest of the algorithm is identical. This is exactly the at-most-k-zeros window.

  2. What if you must delete exactly one zero (not any one element)? Count all 1-separated groups, then for each group of zeros, find the two adjacent runs of ones and their combined length. O(n) with a single pass.

  3. What if the array can contain values other than 0 and 1? Define "bad elements" as those you want to delete. Count them with a budget — same sliding window approach.

  4. What is the maximum subarray of 1s without any deletion (LC 485)? Simply track the current run of 1s and reset on 0. The two-pointer approach here is overkill for that problem.

This Pattern Solves

  • LC 1493 — Longest Subarray of 1s After Deleting One Element (this problem)
  • LC 1004 — Max Consecutive Ones III (at most k zeros, same pattern)
  • LC 424 — Longest Repeating Character Replacement (budget on replacements)
  • LC 992 — Subarrays with K Different Integers (at-least minus at-least)
  • LC 209 — Minimum Size Subarray Sum (minimize window instead of maximize)

Key Takeaways

  • Reframe "delete exactly one element, maximize 1s" as "find the longest window with at most one zero" — the deletion is implicit, and the result is window_length - 1 = right - left.
  • Use zeros to track the zero count in the window; shrink from the left whenever zeros > 1.
  • The formula right - left (not right - left + 1) is the key formula — it accounts for the mandatory one-element deletion automatically.
  • All-ones arrays are handled correctly without special cases: zeros stays 0, and right - left at the end equals n - 1, which is the correct answer when you must delete one of n ones.
  • This generalizes directly to LC 1004 (k flips): change zeros > 1 to zeros > k — one character change in the algorithm.
  • Time O(n), space O(1) — both pointers move forward monotonically, so no element is processed more than twice.
  • Google and Amazon use this to check whether candidates recognize the "at-most-one-bad-element" window reframing and can apply it without introducing an explicit inner loop.

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro

Related reading