这道题目使用最大和问题的分治算法
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;
}
}