Given a binary array nums
, you should delete one element from it.
Return the size of the longest non-empty subarray containing only 1
's in the resulting array. Return 0
if there is no such subarray.
Example 1:
Input: nums = [1,1,0,1] Output: 3 Explanation: After deleting the number in position 2, [1,1,1] contains 3 numbers with value of 1's.
Example 2:
Input: nums = [0,1,1,1,0,1,1,0,1] Output: 5 Explanation: After deleting the number in position 4, [0,1,1,1,1,1,0,1] longest subarray with value of 1's is [1,1,1,1,1].
Example 3:
Input: nums = [1,1,1] Output: 2 Explanation: You must delete one element.
Constraints:
1 <= nums.length <= 105
nums[i]
is either 0
or 1
.Given a binary array nums
, find the length of the longest subarray containing only 1s after deleting at most one element.
This approach iterates through each element in the array, considering it as the element to be deleted. For each deletion, it calculates the length of the longest subarray of 1s.
Algorithm:
Preprocessing: Create two arrays, left
and right
. left[i]
stores the length of the longest consecutive 1s subarray ending at index i
. Similarly, right[i]
stores the length of the longest consecutive 1s subarray starting at index i
.
Iteration: Iterate through the array. For each index i
, consider deleting the element at that index. The length of the longest subarray of 1s after deletion is left[i-1] + right[i+1]
. Update the maximum length found so far.
Return: Return the maximum length found.
Time Complexity: O(n), due to single pass through the array for preprocessing and iteration.
Space Complexity: O(n), due to the left
and right
arrays.
This approach uses a sliding window to efficiently find the longest subarray with at most one 0.
Algorithm:
ans
(maximum length), cnt
(count of 0s), and j
(left pointer) to 0.i
(right pointer) through the array:
nums[i] == 0
, increment cnt
.cnt > 1
, decrement cnt
(by removing elements from the left) and increment j
.ans
with max(ans, i - j + 1)
.ans
.Time Complexity: O(n), as each element is visited at most twice (once by i
and once by j
).
Space Complexity: O(1), as it uses only a few constant extra variables.
This is a slight optimization over Approach 2. Instead of repeatedly moving the left pointer (j
) until cnt <= 1
, it moves it only once when cnt
exceeds 1. This avoids unnecessary iterations while maintaining correctness.
Algorithm:
cnt
(count of 0s), l
(left pointer) to 0.nums[i] == 0
, increment cnt
.cnt > 1
, move the left pointer l
and adjust cnt
accordingly.len(nums) - l - 1
.Time Complexity: O(n) Space Complexity: O(1)
The code examples below demonstrate Approach 2 (Two Pointers) in various languages due to its efficiency and clarity. Approach 3 offers a minor optimization. Approach 1, while correct, is less efficient.
def longestSubarray(nums):
ans = 0
cnt = j = 0
for i, x in enumerate(nums):
cnt += x ^ 1 # Efficiently counts 0s (x ^ 1 is 1 if x is 0, 0 otherwise)
while cnt > 1:
cnt -= nums[j] ^ 1
j += 1
ans = max(ans, i - j + 1)
return ans
class Solution {
public int longestSubarray(int[] nums) {
int ans = 0;
int cnt = 0;
int j = 0;
for (int i = 0; i < nums.length; ++i) {
cnt += nums[i] ^ 1;
while (cnt > 1) {
cnt -= nums[j++] ^ 1;
}
ans = Math.max(ans, i - j + 1);
}
return ans;
}
}
class Solution {
public:
int longestSubarray(vector<int>& nums) {
int ans = 0;
int cnt = 0;
int j = 0;
for (int i = 0; i < nums.size(); ++i) {
cnt += nums[i] ^ 1;
while (cnt > 1) {
cnt -= nums[j++] ^ 1;
}
ans = max(ans, i - j + 1);
}
return ans;
}
};
const longestSubarray = (nums) => {
let ans = 0;
let cnt = 0;
let j = 0;
for (let i = 0; i < nums.length; ++i) {
cnt += nums[i] ^ 1;
while (cnt > 1) {
cnt -= nums[j++] ^ 1;
}
ans = Math.max(ans, i - j + 1);
}
return ans;
};
These code examples all implement the efficient two-pointer approach. Remember to choose the language most suitable for your needs. The time complexity remains O(n) and space complexity O(1) for all these implementations.