数组-最大子数组II-中等

描述
给定一个整数数组,找出两个 不重叠 子数组使得它们的和最大。
每个子数组的数字在数组中的位置应该是连续的。
返回最大的和。
子数组最少包含一个数

样例
给出数组 [1, 3, -1, 2, -1, 2]
这两个子数组分别为 [1, 3] 和 [2, -1, 2] 或者 [1, 3, -1, 2] 和 [2],它们的最大和都是 7
挑战

要求时间复杂度为 O(n)

题目链接

分析

最开始,我打算将该问题转化为求最小连续子数组之和问题,然后用原始数组之和减去最小连续子数组之和,但是发现在很多特例的时候不好使。最后不得不从正向思路出发,对该问题转化为求两个最大连续子数组的问题。

将数组从左向右扫一次,初始化当前最大值结果maxvalue,每次相加之和的结果sum,存放每次操作之和的maxvalue值得数组left。遍历数组,判断sum是否大于0,如果大于零,则sum加上当前数组的值;否则说明这之前没有连续最大子数组,sum等于当前数组的值,从新开始计算。

在每次相加或者赋值sum之后,判断sum和maxvalue的大小,如果sum大,则maxvalue=sum,否则保持maxvalue值不变,用left存下每遍历一个数组之和的maxvalue结果。

然后将数组从右向左扫一次,同样的操作,将maxvalue在每遍历一个数之后放入right数组中。

最后,遍历left,right数组,left[i]+right[i+1]表示在第i位拆分数组,得到其子数组的和。

程序


class Solution {
public:
    /*
     * @param nums: A list of integers
     * @return: An integer denotes the sum of max two non-overlapping subarrays
     */
     
    /*
    从左自右、从右自左分别遍历数组。每次遍历均记录当前最大的单子数组,
    用2个数组left,right保存。如left[i]的值表示nums从0至i中最大子数组的值,
    right[i]的值表示nums从i至size-1中最大子数组的值。
    最后遍历left,right数组,left[i]+right[i+1]
    表示在第i位拆分数组,得到其子数组的和。
    */
    int maxTwoSubArrays(vector<int> &nums) {
        // write your code here
        int size = nums.size();
        int sum,maxvalue;
        int *left = new int[size];
        left[0] = sum = maxvalue =nums[0];
        for(int i = 1; i < size; i++){
            if(sum > 0)
                sum += nums[i];
            else
                sum = nums[i];
            if(sum > maxvalue)
                maxvalue = sum;
            left[i] = maxvalue;
        }
        int *right = new int[size];
        right[size-1] = sum = maxvalue = nums[size-1];
        for(int i = size-2; i >= 0; i--){
            if(sum > 0)
                sum += nums[i];
            else
                sum = nums[i];
            if(sum > maxvalue)
                maxvalue = sum;
            right[i] = maxvalue;
        }
        int result = 0x80000000;
        for(int i = 0; i < size-1; i++){
            result = (result > (left[i]+right[i+1]) ? result : (left[i]+right[i+1]));
        }
        return result;
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值