LeetCoder_____ 最大子序列和(53)

1. 思路A

这个题目是一个很经典的DP(动态规划)问题,我们定义dp[i]表示以i结尾的子序列最大和为多少,那么递推关系就很明确了,对于一个位置X,要么连上前面X+dp[X-1],要么自己单独成为子序列开始X,所以结果就是两者较大值:

d p [ x ] = m a x ( d p [ x − 1 ] , 0 ) + x dp[x]=max(dp[x-1],0)+x dp[x]=max(dp[x1],0)+x

时间复杂度O(n),空间复杂度O(1)




2. 代码A

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




3. 思路B

看题目中提示,题目可以使用分治的方法来做,虽然效率比不上dp但是可以作为一种思路。我们将原数组分为两部分,那么子序列只有可能是以下三种情况:

  • 全部在左边部分
  • 全部在右边部分
  • 一部分在左一部分在右

对于前面两钟情况,我们只需要进行递归即可,那么对于第三种情况,我们可以变成在左边部分找到以最后一个元素结尾的子序列最大和,和在右边部分找到以第一个元素开头的子序列最大和。而这两个只需要累加一遍找最大值即可。

时间复杂度O(nlogn),空间复杂度O(1)




4. 代码B

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        return maxSubArrayRange(nums, 0, nums.size() - 1);
    }

    int maxSubArrayRange(vector<int>& nums, int l, int r)
    {
        if(l == r) return nums[l];
        int mid = (l + r) >> 1;
        return max(
            max(maxSubArrayRange(nums, l, mid), maxSubArrayRange(nums, mid + 1, r)),
            maxSubArrayLeft(nums, l, mid) + maxSubArrayRight(nums, r, mid + 1));
    }
    int maxSubArrayLeft(vector<int>& nums, int l, int pos)
    {
        int sum = 0,ret = nums[pos];
        for(int i = pos; i >= l; i --)
        {
            ret = max(sum += nums[i], ret);
        }
        return ret;
    }
    int maxSubArrayRight(vector<int>& nums, int r, int pos)
    {
        int sum = 0,ret = nums[pos];
        for(int i = pos; i <= r; i ++)
        {
            ret = max(sum += nums[i], ret);
        }
        return ret;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值