53. 最大子序和 - 力扣(LeetCode)

题目描述

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

题解(动态规划)

这里使用的是动态规划的方法。
sums[i]表以nums[i]结尾的连续子序列的最大值
则有以下关系
s u m s [ i ] = { n u m s [ 0 ] if  i  is 0 m a x { s u m s [ i − 1 ] + n u m s [ i ] , n u m s [ i ] } if  i  is not 0 sums[i]= \begin{cases} nums[0] & \quad \text{if } i \text{ is 0}\\ max\{sums[i - 1] + nums[i], nums[i]\} & \quad \text{if } i \text{ is not 0} \end{cases} sums[i]={nums[0]max{sums[i1]+nums[i],nums[i]}if i is 0if i is not 0

代码

*
动态规划
sum[0] = nums[0]
sum[i] = max{sum[i - 1] + nums[i], nums[i]}
时间复杂度为:o(n)
空间复杂度为:o(n)
*/
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        vector<int>sums(nums.size(), 0);
        int max_num = nums[0];
        sums[0] = nums[0];
        for(int i = 1; i < nums.size(); ++i){
            sums[i] = max(sums[i - 1] + nums[i], nums[i]);//求解以nums[i]结尾的最大的连续子序列之和
            max_num = max(max_num, sums[i]);//当前最大
        }
        return max_num;
    }
};

执行结果

在这里插入图片描述

题解(分治法)

一个序列的最大子序和出现的位置无非有三种:左边序列,右边序列,横跨中间数字的序列,而对于左边序列和右边序列仍能进行递归考虑,将问题分解的更小,当只有一个数时,返回这个数,

代码

/*
分治法
时间复杂度为:o(nlogn)

*/
class Solution {
public:
    int maxSub(vector<int>& nums, int beg, int end){
        if(beg == end){
            return nums[beg];
        }
        int l_max_sum, r_max_sum, mid = (beg + end) / 2;
        int l_sum, r_sum, sum;
        l_max_sum = maxSub(nums, beg, mid);//递归求左边序列的最大子序列
        r_max_sum = maxSub(nums, mid + 1, end);//递归求右边序列的最大子序列
        sum = 0;
        l_sum = nums[mid];
        
        //求经过中间元素的最大子序列和
        for(int i = mid; i >= beg; --i){
            sum = sum + nums[i];
            if(sum > l_sum){
                l_sum = sum;
            }
        }
        sum = 0;
        r_sum = nums[mid + 1];
        for(int i = mid + 1; i <= end; ++i){
            sum = sum + nums[i];
            if(sum > r_sum){
                r_sum = sum;
            }
        }
        return max(l_max_sum, max(r_max_sum, l_sum + r_sum)); //返回左、右、中之间最大的
    }
    
    int maxSubArray(vector<int>& nums) {
        return maxSub(nums, 0, nums.size() - 1);
    }
};

执行结果

在这里插入图片描述

你可能感兴趣的:(LeetCode)