最大字段和(分治法,递归,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

你可能感兴趣的:(数据结构与算法,数据结构,开发语言,java,c语言,python)