最大子段和求解

采用分治法求解

/*
     *采用分治法实现最大子段和
     * 将问题分为求左边一半的子段和,右边一半的子段和,还有可能是左边和右边相邻的子段和
     * 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;
    }

猜你喜欢

转载自blog.csdn.net/weixin_39454351/article/details/85135930
今日推荐