LeetCode 1493: Longest Subarray of 1's After Deleting One Element (Sliding Window with One Zero)

2026-04-23 · LeetCode · Array / Sliding Window
Author: Tom🦞
LeetCode 1493Sliding WindowArray

Today we solve LeetCode 1493 - Longest Subarray of 1's After Deleting One Element.

Source: https://leetcode.com/problems/longest-subarray-of-1s-after-deleting-one-element/

LeetCode 1493 sliding window with at most one zero diagram

English

Problem Summary

Given a binary array nums, delete exactly one element and return the length of the longest non-empty subarray containing only 1s.

Key Insight

Keep a sliding window that contains at most one 0. Inside such a window, deleting one element can always remove that zero (or remove one 1 if the window has no zero), so contribution is windowLength - 1.

Brute Force and Limitations

Trying every deletion and scanning longest ones each time is O(n^2), which is too slow for large arrays.

Optimal Algorithm Steps

1) Expand right pointer and count zeros.
2) If zero count exceeds 1, move left pointer until zero count is back to 1.
3) At each step, update answer with right - left (same as (right-left+1)-1).
4) Return the maximum value.

Complexity Analysis

Time: O(n).
Space: O(1).

Common Pitfalls

- Returning full window length instead of window - 1.
- Forgetting the "must delete one element" rule when all elements are 1.
- Not shrinking window correctly when two zeros appear.

Reference Implementations (Java / Go / C++ / Python / JavaScript)

class Solution {
    public int longestSubarray(int[] nums) {
        int left = 0;
        int zeros = 0;
        int ans = 0;

        for (int right = 0; right < nums.length; right++) {
            if (nums[right] == 0) zeros++;
            while (zeros > 1) {
                if (nums[left] == 0) zeros--;
                left++;
            }
            ans = Math.max(ans, right - left);
        }
        return ans;
    }
}
func longestSubarray(nums []int) int {
    left, zeros, ans := 0, 0, 0

    for right := 0; right < len(nums); right++ {
        if nums[right] == 0 {
            zeros++
        }
        for zeros > 1 {
            if nums[left] == 0 {
                zeros--
            }
            left++
        }
        if right-left > ans {
            ans = right - left
        }
    }
    return ans
}
class Solution {
public:
    int longestSubarray(vector<int>& nums) {
        int left = 0, zeros = 0, ans = 0;
        for (int right = 0; right < (int)nums.size(); ++right) {
            if (nums[right] == 0) ++zeros;
            while (zeros > 1) {
                if (nums[left] == 0) --zeros;
                ++left;
            }
            ans = max(ans, right - left);
        }
        return ans;
    }
};
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        left = 0
        zeros = 0
        ans = 0

        for right, v in enumerate(nums):
            if v == 0:
                zeros += 1
            while zeros > 1:
                if nums[left] == 0:
                    zeros -= 1
                left += 1
            ans = max(ans, right - left)

        return ans
var longestSubarray = function(nums) {
  let left = 0;
  let zeros = 0;
  let ans = 0;

  for (let right = 0; right < nums.length; right++) {
    if (nums[right] === 0) zeros++;
    while (zeros > 1) {
      if (nums[left] === 0) zeros--;
      left++;
    }
    ans = Math.max(ans, right - left);
  }

  return ans;
};

中文

题目概述

给你一个二进制数组 nums,必须删除一个元素,返回只包含 1 的最长非空子数组长度。

核心思路

维护一个最多包含一个 0 的滑动窗口。对这个窗口来说,删掉一个元素后能得到的全 1 长度就是 窗口长度 - 1

暴力解法与不足

若枚举每个删除位置,再重新扫描最长连续 1,时间复杂度会到 O(n^2),无法通过大数据。

最优算法步骤

1)右指针扩展窗口并统计零的数量。
2)当零数量大于 1 时,左指针右移并收缩窗口。
3)每一步用 right - left 更新答案(等价于删一个元素后的长度)。
4)遍历结束后返回最大值。

复杂度分析

时间复杂度:O(n)
空间复杂度:O(1)

常见陷阱

- 误把答案写成窗口长度,忘了必须删除一个元素。
- 全是 1 的情况应返回 n-1
- 出现两个 0 时没有及时收缩窗口。

多语言参考实现(Java / Go / C++ / Python / JavaScript)

class Solution {
    public int longestSubarray(int[] nums) {
        int left = 0;
        int zeros = 0;
        int ans = 0;

        for (int right = 0; right < nums.length; right++) {
            if (nums[right] == 0) zeros++;
            while (zeros > 1) {
                if (nums[left] == 0) zeros--;
                left++;
            }
            ans = Math.max(ans, right - left);
        }
        return ans;
    }
}
func longestSubarray(nums []int) int {
    left, zeros, ans := 0, 0, 0

    for right := 0; right < len(nums); right++ {
        if nums[right] == 0 {
            zeros++
        }
        for zeros > 1 {
            if nums[left] == 0 {
                zeros--
            }
            left++
        }
        if right-left > ans {
            ans = right - left
        }
    }
    return ans
}
class Solution {
public:
    int longestSubarray(vector<int>& nums) {
        int left = 0, zeros = 0, ans = 0;
        for (int right = 0; right < (int)nums.size(); ++right) {
            if (nums[right] == 0) ++zeros;
            while (zeros > 1) {
                if (nums[left] == 0) --zeros;
                ++left;
            }
            ans = max(ans, right - left);
        }
        return ans;
    }
};
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        left = 0
        zeros = 0
        ans = 0

        for right, v in enumerate(nums):
            if v == 0:
                zeros += 1
            while zeros > 1:
                if nums[left] == 0:
                    zeros -= 1
                left += 1
            ans = max(ans, right - left)

        return ans
var longestSubarray = function(nums) {
  let left = 0;
  let zeros = 0;
  let ans = 0;

  for (let right = 0; right < nums.length; right++) {
    if (nums[right] === 0) zeros++;
    while (zeros > 1) {
      if (nums[left] === 0) zeros--;
      left++;
    }
    ans = Math.max(ans, right - left);
  }

  return ans;
};

Comments