最大子序列和.md

public class MaxSubSum {
    public static int[] queue = { 1, -2, 9 , -5, 6 , -3, -2, 10, -3, 8, -7 , 10 };

    public int maxSubSum_ON3(int[] array) {
        if (array.length == 0) return 0;
        int maxSubSum = 0;
        for (int i=0; i<array.length; i++) {
            for (int j=i; j<array.length; j++) { 
                int tempSum = 0;               
                for(int k=i; k<=j; k++) {
                    tempSum += array[k];
                }
                if (tempSum > maxSubSum) maxSubSum = tempSum;
            }
        }
        return maxSubSum;
    }

    public int maxSubSum_ON2(int[] array) {
        if (array.length == 0) return 0;
        int maxSubSum = 0;
        for (int i=0; i < array.length; i++) {
            int tempSum = 0;
            for (int j=i;j<array.length; j++) {
                tempSum += array[j];
                if (tempSum > maxSubSum)
                    maxSubSum = tempSum;
            }
        }
        return maxSubSum;
    }

    /** * 采用分治思想,将一段序列分成两部分,分别计算前后子序列的最大子序列和 * 然后和包含center点的最大子序列和相对比 */
    public int maxSubSum_ONLOGN(int[] array, int left, int right) {
        if (left == right) {
            return array[left]>0?array[left]:0;
        }
        int center = (left + right)/2;
        int maxLeftSubSum = maxSubSum_ONLOGN(array, left, center);
        int maxRrightSubSum = maxSubSum_ONLOGN(array, center+1, right);

        // caculator array[center]'s max sub sum.
        int leftBroadSum = 0, maxLeftBroadSum = 0;
        for (int i = center; i >= left; i--) {
            leftBroadSum += array[i];
            if (leftBroadSum > maxLeftBroadSum)
                maxLeftBroadSum = leftBroadSum;
        }

        int rightBroadSum = 0, maxRightBroadSum = 0;
        for (int i = center+1; i <= right; i++) {
            rightBroadSum += array[i];
            if (rightBroadSum > maxRightBroadSum)
                maxRightBroadSum = rightBroadSum;
        }

        return max(maxLeftSubSum, maxRrightSubSum, maxLeftBroadSum + maxRightBroadSum);
    }

    private int max(int a, int b, int c) {
        if (a>b) return a>c?a:c;
        else return b>c?b:c;
    }

    /** * 这里其实是利用了规律,如果子序列 Am~An 的和小于0, * 那么m-n这个之间的序列必定不会被n+1以后的序列包含。 * 此时最大子序列和就是An之前和An+1的最大子序列和中的较大值 */
    public int maxSubSum_ON(int[] array) {
        if (array.length == 0) return 0;
        int maxSubSum = 0, tempSum = 0;
        for (int i = 0; i < array.length; i++) {
            tempSum += array[i];
            if (tempSum > maxSubSum) 
                maxSubSum = tempSum;
            else if (tempSum < 0)
                tempSum = 0; // Cool...
        }

        return maxSubSum;
    }

    public static void main(String[] args) {
        MaxSubSum maxSubSum = new MaxSubSum();
        System.out.println(maxSubSum.maxSubSum_ON3(queue));
        System.out.println(maxSubSum.maxSubSum_ON2(queue));
        System.out.println(maxSubSum.maxSubSum_ONLOGN(queue, 0, queue.length-1));
        System.out.println(maxSubSum.maxSubSum_ON(queue));
    }
}
点赞