力扣每日一题+最大数组和

彦祖天天见

题目:53.最大子数组和

题目要求:

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

第一种解法:动态规划

由题可知,到第i个位置的最大数组和的选择是继续保持i个位置的最大数组和,或者由i-1个位置的最大数组和加上第i个位置,其代码如下:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if(nums.size() == 0)     return 0;
        vector<int> dp(nums.size(),0);
        dp[0] = nums[0];
        int res=dp[0];
        for(int i=1;i<nums.size();i++){
            dp[i]=max(dp[i-1]+nums[i],nums[i]);
            if(dp[i] > res)     res = dp[i];
        }
        return res;
    }
};

第二种解法:贪心

贪心采用累加的方式计算最大数组和,如果和为负数则马上丢弃当前位置,从下一位置重新计算;

每次循环将计算得到的最大值存入结果。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int count=0;
        int res=nums[0];
        for(int i=0;i<nums.size();i++){
            count +=nums[i];
            res = res>count?res:count;

            if(count<0) count=0;
        }
        return res;
    }
};

这一题是由上面题目演变而来

题目:1911.最大子序列交替和

题目要求:

一个下标从 0 开始的数组的 交替和 定义为 偶数 下标处元素之 和 减去 奇数 下标处元素之 和 。

    比方说,数组 [4,2,5,3] 的交替和为 (4 + 5) - (2 + 3) = 4 。

给你一个数组 nums ,请你返回 nums 中任意子序列的 最大交替和 (子序列的下标 重新 从 0 开始编号)。

一个数组的 子序列 是从原数组中删除一些元素后(也可能一个也不删除)剩余元素不改变顺序组成的数组。比方说,[2,7,4] 是 [4,2,3,7,2,1,4] 的一个子序列(加粗元素),但是 [2,4,2] 不是。

示例 1:

输入:nums = [4,2,5,3]
输出:7
解释:最优子序列为 [4,2,5] ,交替和为 (4 + 5) - 2 = 7 。

示例 2:

输入:nums = [5,6,7,8]
输出:8
解释:最优子序列为 [8] ,交替和为 8 。

示例 3:

输入:nums = [6,2,1,2,4,5]
输出:10
解释:最优子序列为 [6,1,5] ,交替和为 (6 + 5) - 1 = 10 。

由题目可知结果由偶数下标和减去奇数下标和,所以奇数下标的元素符号为-i,偶数下标的元素符号为i   使用两个vector容器来存储奇数和偶数的最大和,然后从中比较最大者。

偶数方程表示,以nums[i-1]结尾的最大交替和的偶数项ou[i],可以选择不包含nums[i-1],即继承前一个奇数项的最大交替和ou[i-1];或者选择包含nums[i-1],即前一个奇数项的最大交替和ji[i-1]减去nums[i-1]

这个方程表示,以nums[i-1]结尾的最大交替和的奇数项ji[i],可以选择不包含nums[i-1],即继承前一个偶数项的最大交替和ji[i-1];或者选择包含nums[i-1],即前一个偶数项的最大交替和ou[i-1]加上nums[i-1]

通过不断更新ou[i]ji[i],最终可以得到以nums[n-1]结尾的最大交替和的偶数项ou[n]和奇数项ji[n],其中nnums的大小。

最后,返回max(ou[n], ji[n])作为最大交替和的结果。

class Solution {
public:
    long long maxAlternatingSum(vector<int>& nums) {

        int n=nums.size();
        if(n == 1)    return nums[0];
        vector<long long> ou(n+1),ji(n+1);
        for(int i=1;i<=n;i++){
            ou[i]=max(ou[i-1],ji[i-1]-nums[i-1]);
            ji[i]=max(ji[i-1],ou[i-1]+nums[i-1]);
        }
        return max(ou[n],ji[n]);
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值