给你一个二进制数组 nums ,你需要从中删掉一个元素。
请你在删掉元素的结果数组中,返回最长的且只包含 1 的非空子数组的长度。
如果不存在这样的子数组,请返回 0 。
提示 1:
输入:nums = [1,1,0,1]
输出:3
解释:删掉位置 2 的数后,[1,1,1] 包含 3 个 1 。
示例 2:
输入:nums = [0,1,1,1,0,1,1,0,1]
输出:5
解释:删掉位置 4 的数字后,[0,1,1,1,1,1,0,1] 的最长全 1 子数组为 [1,1,1,1,1] 。
示例 3:
输入:nums = [1,1,1]
输出:2
解释:你必须要删除一个元素。

递推
class Solution {
public:
int longestSubarray(vector<int>& nums) {
int n = nums.size();
vector<int> pre(n), suf(n);
pre[0] = nums[0];
for(int i = 1; i < n; i++){
pre[i] = nums[i] ? pre[i-1] + 1 : 0;
}
suf[n-1] = nums[n-1];
for(int i = n-2; i >= 0; i--){
suf[i] = nums[i] ? suf[i+1] + 1 : 0;
}
int maxSum = 0;
for(int i = 0; i < n; i++){
int preSum = i == 0 ? 0 : pre[i-1];
int sufSum = i == n-1 ? 0 : suf[i+1];
maxSum = max(maxSum, preSum + sufSum);
}
return maxSum;
}
};
时间复杂度:O(n)。这里对原数组进行三次遍历,每次时间代价为 O(n),故渐进时间复杂度为 O(n)。
空间复杂度:O(n)。这里预处理 pre 和 suf 需要两个长度为 n 的数组。
我们可以定义两个数组,一个pre[i]来记录以i结尾的最大连续1的数量,一个suf[i]用来记录以i开头的最大连续1的数量,然后我们遍历每个元素作为删除的元素,然后就可以知道如果删除了这个元素,那么pre[i-1]和suf[i+1]的和就是最大连续1的数量。需要注意的是边界条件,由于当i=0的时候,pre[i-1]没有意义,当i=n-1的时候,suf[i+1]没有意义,所以我们要定义这两种情况。有人会问不能从i=1遍历到i<n-1吗?那么当nums=[0,1,0]的时候,输出为0,但实际上答案是1。
空间优化
class Solution {
public:
int longestSubarray(vector<int>& nums) {
int p0 = 0;
int p1 = 0;
int ans = 0;
for(int num : nums){
if(num == 0){
p1 = p0;
p0 = 0;
}
else{
p1++;
p0++;
}
ans = max(ans, p1);
}
if(ans == nums.size()){
ans--;
}
return ans;
}
};
时间复杂度:O(n)。这里对原数组进行一次遍历,时间代价为 O(n),故渐进时间复杂度为 O(n)。
空间复杂度:O(1)。
很好的优化,我们只需要定义两个变量p0和p1,p1用来表示删除一个元素0(也可以不删除)保持的最大的连续1的数量,p0代表的是0之间的1的数量。举个例子:
假设nums = {1, 1, 0, 1, 1, 1, 0, 1, 1}
初始化 p0 = 0,p1 = 0,ans = 0。
遍历第一个元素 1:
p0 和 p1 同时增加,p0 = 1,p1 = 1。
更新 ans = max(ans, p1) = 1。
遍历第二个元素 1:
p0 = 2,p1 = 2。
更新 ans = max(ans, p1) = 2。
遍历第三个元素 0:
p1 = p0 = 2(假设删除这个 0 后的连续 1 长度为 2),然后 p0 = 0。
更新 ans = max(ans, p1) = 2。
遍历第四个元素 1:
p0 = 1,p1 = 3(删除之前的 0 后,加上当前的 1,所以 p1 增加)。
更新 ans = max(ans, p1) = 3。
遍历第五个元素 1:
p0 = 2,p1 = 4。
更新 ans = max(ans, p1) = 4。
遍历第六个元素 1:
p0 = 3,p1 = 5。
更新 ans = max(ans, p1) = 5。
遍历第七个元素 0:
p1 = p0 = 3(假设删除这个 0 后的连续 1 长度为 3),然后 p0 = 0。
ans = max(ans, p1) = 5(不变)。
遍历第八个元素 1:
p0 = 1,p1 = 4。
更新 ans = max(ans, p1) = 5。
遍历第九个元素 1:
p0 = 2,p1 = 5。
ans = max(ans, p1) = 5(不变)。

1215

被折叠的 条评论
为什么被折叠?



