uacs2024

导航

leetcode 1493. 删掉一个元素以后全为 1 的最长子数组

1493. 删掉一个元素以后全为 1 的最长子数组

法一:递推

class Solution {
public:
//在删掉元素的结果数组中,最长的且只包含 1 的非空子数组存在两种情况:
//1.这个子数组在原数组中本身就是连续的,无论删或者不删其他的元素,它都是最长的且只包含 1 的非空子数组;
//2.这个子数组原本不连续,而是两个连续的全 1 子数组,中间夹着一个 0,把这个 0 删掉以后,左右两个子数组组合成一个最长的且只包含 1 的非空子数组。
//我们可以枚举被删除的位置,假设下标为 i,我们希望知道「以第 i−1 位结尾的最长连续全 1 子数组」和「以第 i+1 位开头的最长连续全 1 子数组」的长度分别是多少
//这两个量的和就是删除第 i 位之后最长的且只包含 1 的非空子数组的长度。假设我们可以得到这两个量,我们只要枚举所有的 i,就可以得到最终的答案。
//我们可以对原数组做一次正向遍历,预处理出 pre,再做一次反向遍历,预处理出 suf。
//最后我们枚举所有的元素作为待删除的元素,计算出删除这些元素之后最长的且只包含 1 的非空子数组的长度,比较并取最大值。

    int longestSubarray(vector<int>& nums) {
        int size = nums.size(),resMax = 0;
        vector<int> pre(size),suf(size);

        pre[0] = nums[0];//数组pre[i]表示以 pre[i] 结尾的最长连续 1 的长度
        for(int i = 1;i < size;i++){
            if(nums[i] == 0)  pre[i] = 0;
            else  pre[i] = pre[i-1] + 1;
        }

        suf[size - 1] = nums[size - 1];//suf[i]表示以 suf[i] 开头的最长连续 1 的长度
        for(int i = size-2;i >= 0;i--){
            if(nums[i] == 0)  suf[i] = 0;
            else  suf[i] = suf[i+1] + 1;
        }

        for(int i = 0;i < size;i++){
            int preSum,sufSum;
            if(i == 0)  preSum = 0;//单防i = 0
            else  preSum = pre[i-1];

            if(i == size-1)  sufSum = 0;//单防i = size-1
            else  sufSum = suf[i+1];

            resMax = max(resMax,preSum + sufSum);
        }
        return resMax;
    }
};

法二:递推优化

 

class Solution {
public:
//进一步优化,使用一次递推
//记p0(i) 为「以第 i 位结尾的最长连续全 1 子数组」
//同时,我们记 p1(i) 为「以第 i 位结尾,并且可以在某个位置删除一个 0 的最长连续全 1 子数组」。
//注意这里我们规定了只删除 0,而不是任意一个元素,这是因为只要数组中的元素不全为 1,那么删除 1 就没有任何意义。
//当我们遇到 1 时,p1(i)的递推式与p0(i)相同;而当我们遇到 0 时,由于p1(i)允许删除一个 0,那么我们可以把这个 0 删除,将p0(i−1) 的值赋予p1(i)。
//最后的答案即为p1(i) 中的最大值。当遇到数组中的元素全为 1 的特殊情况时,我们需要将答案减去 1,这是因为在这种情况下,我们不得不删除一个 1。
//注意到递推式中所有的 p0(i),p1(i) 只和 p0(i−1),p1(i−1) 相关,因此我们可以直接使用两个变量进行递推,减少空间复杂度。

    int longestSubarray(vector<int>& nums) {
        int resMax = 0,p0 = 0,p1 = 0;
        for(int &num : nums){
            if(num == 0){
                p1 = p0;
                p0 = 0;
            }
            else{
                ++p0;++p1;
            }
            resMax = max(resMax,p1);
        }
        if(resMax == nums.size())  --resMax;
        return resMax;
    }
};

 

posted on 2024-12-07 18:27  ᶜʸᵃⁿ  阅读(64)  评论(0)    收藏  举报