最大字段和(分治法,递归,Java)

分析

这里我们以数组 arr[]={-20,11,-4,13,-5,-2};  为例

求子区间及最大和,从结构上是非常适合分治法的,因为所有子区间[start, end]只可能有以下三种可能性:

在[0, (arr.length-1)/2]这个区域内
在[(arr.length-1)/2+1, arr.length-1]这个区域内
起点位于[0, (arr.length-1)/2],终点位于[(arr.length-1)/2+1, arr.length-1]内


以上三种情形的最大者,即为所求. 前两种情形符合子问题递归特性,所以递归可以求出. 对于第三种情形,则需要单独处理. 第三种情形必然包括了 (arr.length-1)/2 和 (arr.length-1)/2+1 两个位置,这样就可以利用第二种穷举的思路求出:

1. 以(arr.length-1)/2为终点,往左移动扩张,求出和最大的一个leftSum
2. 以(arr.length-1)/2+1为起点,往右移动扩张,求出和最大的一个rightSum
3. leftSum+rightSum=midSum      midSum是第三种情况可能的最大值


//最大子段
public class Maxsize {
    public static void main(String[] args) {
        int arr[]={-20,11,-4,13,-5,-2};
        System.out.println(maxsize(arr,0,arr.length-1));


    }
    public static int maxsize(int[] arr, int left, int right){
        int sum=0,midSum=0,leftSum=0,rightSum=0;
        int center,s1,s2,lefts,rights;
        //如果序列长度为1时
        if (left==right){
            sum=arr[left];
        }
        else {
            //划分
            center=(left+right)/2;
            //左递归
            leftSum=maxsize(arr,left,center);
            //又递归
            rightSum=maxsize(arr,center+1,right);

            s1=0;lefts=0;
            for (int i=center;i>=left;i--){
                lefts+=arr[i];
                if (lefts>s1){
                    s1=lefts;
                }
            }

            s2=0;rights=0;
            for (int j=center+1;j<=right;j++){
                rights+=arr[j];
                if (rights>s2){
                    s2=rights;
                }
            }

            midSum=s1+s2;
            if (midSum<leftSum){
                sum=leftSum;
            }
            else {
                sum=midSum;
            }
            if (sum<rightSum){
                sum=rightSum;
            }

        }




        return sum;
    }
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热爱编程的小白白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值