LeetCode:最大子序和 (分治法+动态规划)

二分法

将nums[0:n]分解为nums【left:center】,nums【center+1:right】 ,分三种情况求解

 

  1. LEFT:nums【left:right】= nums【left:center】
  2. RIGHT:nums【left:right】= nums【center:right】
  3. MIDDLE:nums【left:right】=s1+s2

对于3,nums【center】和nums【center+1】一定在序列中,从center向左求最大值,center+1向右求最大值,相加。

 

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if(nums.size() == 0) return 0;
        return (max_sub(nums,0,nums.size()-1));
    }
    
    int max_sub(vector<int>& nums,int left,int right)
    {
        if(left == right)
            return nums[left];
            
        int center,left_sum,right_sum,s1=INT_MIN,s2=INT_MIN,l=0,r=0;
        center = (left + right)/2;
        
        left_sum=max_sub(nums,left,center);//left
        
        right_sum=max_sub(nums,center+1,right);//right
        
        for(int i = center;i>=left;i--)//middle
        {
            l = l+nums[i];
            if(s1<l) s1= l;
        }
        
        for(int i = center+1;i<=right;i++)
        {
            r = r+nums[i];
            if(s2<r) s2= r;
        }
        
        if(left_sum > right_sum && left_sum > (s1+s2))//judge
            return left_sum;
        else if(right_sum > (s1+s2))
            return right_sum;
        else return s1+s2;
    }
};

动态规划

用result[i]保存以数字nums[i]结尾的最大子序和,以nums【0】结尾的只有nums【0】本身,result【0】=nums【0】

result【1】=MAX(nums【1】,result【0】+nums【1】)

以此类推

 

 

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

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值