leetcode(53)Maximum Subarray

题意:找到最大子数组的和。

分析:用分治法。假设把一个数组[low,high]分成两半[low,mid]和[mid,high],那么[low,high]的最大子序列之和只可能是以下三者中的最大值:

           1、[low,mid]的最大子序列之和。

           2、[mid+1,high]的最大子序列之和。

           3、一个横跨[low,mid]和[mid+1,high]的最大子序列之和。

     其中横跨[low,mid]和[mid,high]的最大子序列和可以在O(n)时间内计算出来。计算方法是:首先计算A[mid]+A[mid-1]+A[mid-2]+...+A[low],把计算过程中的和的最大值记下来,记为MaxSum1,MaxSum1就是从中间往左边扩展能得到的最大的和。然后计算A[mid+1]+A[mid+2]+...+A[high],把计算过程中的和的最大值记下来,记为MaxSum2,MaxSum2就是从中间往右边扩展能得到的最大的和。于是(MaxSum1+MaxSum2)就是横跨[low,mid]和[mid,high]的最大子序列之和。

     这样就能使用分治法求解,并且T(n)=2T(n/2)+O(n),根据主定理得算法的时间复杂度是O(nlgn)。


代码:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        return maxSubArray(0,nums.size()-1,nums);
    }
    int maxSubArray(int low,int high,vector<int>& nums)
    {
        if(low==high) return nums[low];
        int mid=(low+high)/2;
        int leftMax=maxSubArray(low,mid,nums);
        int rightMax=maxSubArray(mid+1,high,nums);
        int sum=0,sumMax1=nums[mid],sumMax2=nums[mid+1];
        for(int i=mid;i>=low;i--)
        {
            sum+=nums[i];
            if(sum>=sumMax1) sumMax1=sum;
        }
        sum=0;
        for(int i=mid+1;i<=high;i++)
        {
            sum+=nums[i];
            if(sum>=sumMax2) sumMax2=sum;
        }
        return max(max(leftMax,rightMax),sumMax1+sumMax2);
    }
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值