连续子序列最大和

这道题目使用最大和问题的分治算法

package com.divide.cc;
/**
 * 
 * @author SunnyBoy
 * runtime is O(NlogN)
 */
public class SumSequence {
    public static void main(String[] args) {
        int[] a = { 10, 2, -1, -3, 2, -1, 7, -5, 3, 5, 7 };
        int maxSum = maxSubsequenceSum(a);
        System.out.println(maxSum);
    }
    /**
     * 递归地计算整个位于前半部地连续子序列最大和
     * 递归地计算整个位于后半部地连续子序列最大和
     * 通过两个连续循环,计算从前半部开始但在后半部不结束地连续子序列地最大和
     * 从这三个连续子序列最大和中找出一个最大值,即是连续子序列最大和
     * @param a
     * @param left
     * @param right
     * @return
     */

    private static int maxSumRec(int[] a, int left, int right) {
        int maxLeftBorderSum = 0, maxRightBorderSum = 0;
        int leftBorderSum = 0, rightBorderSum = 0;
        int center = (left + right) / 2;
        if (left == right)
            return a[left] > 0 ? a[left] : 0;
        int maxLeftSum = maxSumRec(a, left, center);
        int maxRightSum = maxSumRec(a, center + 1, right);
        for (int i = center; i >= left; i--) {
            leftBorderSum += a[i];
            if (leftBorderSum > maxLeftBorderSum)
                maxLeftBorderSum = leftBorderSum;
        }
        for (int i = center; i <= right; i++) {
            rightBorderSum += a[i];
            if (rightBorderSum > maxRightBorderSum) {
                maxRightBorderSum = rightBorderSum;
            }
        }
        return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightSum);
    }

    private static int maxSubsequenceSum(int[] a) {
        return a.length>0? maxSumRec(a,0,a.length-1) : 0;
    }

    private static int max3(int maxLeftSum, int maxRightSum, int i) {
        int max = maxLeftSum > maxRightSum ? maxLeftSum : maxRightSum;
        max = max > i ? max : i;
        return max;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值