首页 > 其他分享 >leetcode 1493. 删掉一个元素以后全为 1 的最长子数组

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

时间:2024-12-07 18:32:06浏览次数:4  
标签:suf p0 p1 resMax 删掉 1493 数组 leetcode size

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;
    }
};

 

标签:suf,p0,p1,resMax,删掉,1493,数组,leetcode,size
From: https://www.cnblogs.com/uacs2024/p/18592516

相关文章

  • 【Leetcode Top 100】146. LRU 缓存
    问题背景请你设计并实现一个满足LRU(最近最少使用)缓存约束的数据结构。实现LRUCache类:LRUCache(intcapacity)以正整数作为容量cap......
  • 【Leetcode 每日一题】688. 骑士在棋盘上的概率
    问题背景在一个n×nn\timesnn×n的国际象棋棋盘上,一个骑士从单元格......
  • LeetCode 263[丑数]
    题目链接LeetCode263[丑数]详情实例提示题解思考题目对丑数的定义:只包含质因数2、3、5的正整数条件一:只包含质因数2、3、5条件二:正整数 对于条件二很好筛选:如果给定值n小于1,即给定值为0或者是负数,此时条件二不满足,则返回false该部分的代码实现如下:......
  • leetcode3288 最长上升路径的长度
    给定长度为n的二维数组{x[i],y[i]}和一个整数k,其中0<=k<n,从中选中若干个点排序构成序列,求最长的点序列满足x[i]<x[i+1]并且y[i]<y[i+1],要求第k个点必须选择,返回最长序列的长度。1<=n<=1E5;0<=x[i],y[i]<=1E9;各个点互不相同分析:可以拆分成如下几个子任务:(1)求一维数组的lis的长度......
  • leetcode-1193. 每月交易 I
     建表语句:CreatetableIfNotExistsTransactions(idint,countryvarchar(4),stateenum('approved','declined'),amountint,trans_datedate)TruncatetableTransactionsinsertintoTransactions(id,country,state,amount,trans_date)......
  • leetcode 3266. K 次乘运算后的最终数组 II
    3266.K次乘运算后的最终数组II给你一个整数数组 nums ,一个整数 k  和一个整数 multiplier 。你需要对 nums 执行 k 次操作,每次操作中:找到 nums 中的 最小 值 x ,如果存在多个最小值,选择最 前面 的一个。将 x 替换为 x*multiplier 。k 次操作以......
  • leetcode 3. 无重复字符的最长子串
    3.无重复字符的最长子串给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。 滑动窗口模板//外层循环扩展右边界,内层循环扩展左边界for(intl=0,r=0;r<n;r++){//当前考虑的元素while(l<=r&&check()){//区间[left,right]不符......
  • leetcode第4题 如何求出两个有序数组的中位数
    leetcode原题大意,给定两个升序排列的有序数组,例如nums1=[1,2],nums2=[3,4]那么,这两个有序数组的所有数字的中位数为(2+3)/2=1.5,现在要求以O(log(m+n))的时间复杂度。funcfindMedianSortedArrays(nums1[]int,nums2[]int)float64{ length:=len(nums1)+len(nums2) ......
  • 2024/12/6 【哈希表】LeetCode1.两数之和 【√】
    解法1:暴力解法classSolution:deftwoSum(self,nums:List[int],target:int)->List[int]:foriinrange(len(nums)):des=target-nums[i]ifdesinnums:forjinrange(len(nums)):......
  • LeetCode LCR072[x的平方根]
    题目链接LeetCodeLCR072[x的平方根]详情实例提示题解思路一[暴力法]由于所求的是整型且是正符号整型,可以采取循环遍历的方式来求取平方根用for循环将i由0开始遍历循环体:求i的平方值当平方值小于指定值,此时循环继续退出循环的条件:当平方值为指定值时,返回......