最大子段和求解

采用分治法求解

/*
     *采用分治法实现最大子段和
     * 将问题分为求左边一半的子段和,右边一半的子段和,还有可能是左边和右边相邻的子段和
     * 1-n 分为1-n/2,     n/2+1---n,      m--n/2 n/2+1--k
     *
      */
public static int max_sub(int[] a,int start, int end)
    {

        int center,left_max,right_max,sum,left_sum,right_sum;
        //根据中间划分两段
        center = (start+end)/2;
//        终止条件,负数取零
        if(start==end){
            return a[start]>0?a[start]:0;
        }else {
//            递归左边最大子段和
            left_max=max_sub(a,start,center);
//            递归右边最大子段和
            right_max=max_sub(a,center+1,end);
//            最大子段和可能经过中间
            sum=0;
            left_sum=0;
            for(int i=center;i>=start;i--) {
                sum+=a[i];
                if(sum>left_sum)
                    left_sum=sum;
            }
            sum=0;
            right_sum=0;
            for(int i=center+1;i<=end;i++){
                sum+=a[i];
                if(sum>right_sum)
                    right_sum=sum;
            }
            sum=right_sum+left_sum;
//            取三种情况最大值为最大子段和返回值
            if(sum<left_max)
                sum=left_max;
            if (sum<right_max)
                sum=right_max;
            return sum;
        }
    }

利用动态规划求解

/*
*****************************
* 动态规划解决最大子段和
* 数组元素b[j]=max(a[i]+a[i+1]+..+a[j]),其中1<=i<=j,并且i<=j<=n。
* 则所求的最大子段和为max b[j],1<=j<=n。
 */
    public static int dy_max_sub(int[] a,int start,int end)
    {
        int max;
        int[] b = new int[a.length];
        max=b[0]=a[0];
        for(int i=start+1;i<=end;i++)
        {
            if(b[i-1]>0)
                b[i]=b[i-1]+a[i];
            else
                b[i]=a[i];
            if(b[i]>max)
                max=b[i];
        }
        return max;
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值