以下代码主要来自于《数据结构与算法分析 Java语言描述》第二章,增加了一些打印的log。
public class MaxSubSumTest { public static void main(String[] args) { int[] testArray = new int[]{-2, 11, -4, 13, -5, -2}; System.out.println("maxSubSum1: " + maxSubSum1(testArray)); System.out.println("maxSubSum2: " + maxSubSum2(testArray)); System.out.println("maxSubSum3: " + maxSubSum3(testArray)); System.out.println("maxSubSum4: " + maxSubSum4(testArray)); } public static int maxSubSum1(int[] a) { System.out.println("------maxSubSum1--------"); long startTime = System.currentTimeMillis(); int maxSum = 0; for (int i = 0; i < a.length; i++) { for (int j = i; j < a.length; j++) { int thisSum = 0; for (int k = i; k <= j; k++) { thisSum += a[k]; System.out.print(" a[" + k + "] "); } System.out.println("-->" + thisSum); if (thisSum > maxSum) { maxSum = thisSum; } } } long endTime = System.currentTimeMillis(); System.out.println(startTime + "--->" + endTime); System.out.println("------maxSubSum1 return--------"); System.out.println("------" + (endTime - startTime) + " millis--------"); return maxSum; } public static int maxSubSum2(int[] a) { System.out.println("------maxSubSum2--------"); long startTime = System.currentTimeMillis(); int maxSum = 0; for (int i = 0; i < a.length; i++) { int thisSum = 0; for (int j = i; j < a.length; j++) { thisSum += a[j]; System.out.print(" a[" + i + "-" + j + "] "); System.out.println("-->" + thisSum); if (thisSum > maxSum) { maxSum = thisSum; } } } long endTime = System.currentTimeMillis(); System.out.println(startTime + "--->" + endTime); System.out.println("------maxSubSum2 return--------"); System.out.println("------" + (endTime - startTime) + " millis--------"); return maxSum; } public static int maxSubSum3(int[] a) { return maxSumRec(a, 0, a.length - 1); } private static int maxSumRec(int[] a, int left, int right) { if (left == right) { if (a[left] > 0) { return a[left]; } else { return 0; } } int center = (left + right) / 2; int maxLeftSum = maxSumRec(a, left, center); int maxRightSum = maxSumRec(a, center + 1, right); int maxLeftBorderSum = 0; int leftBorderSum = 0; for (int i = center; i >= left; i--) { leftBorderSum += a[i]; if (leftBorderSum > maxLeftBorderSum) { maxLeftBorderSum = leftBorderSum; } } int maxRightBorderSum = 0; int rightBorderSum = 0; for (int i = center + 1; i <= right; i++) { rightBorderSum += a[i]; if (rightBorderSum > maxRightBorderSum) { maxRightBorderSum = rightBorderSum; } } System.out.println("left: " + left + ", right: " + right); System.out.println("maxleft: " + maxLeftBorderSum + ", maxright: " + maxRightSum + ", " + "maxLeftBorderSum: " + maxLeftBorderSum + " maxRightBorderSum: " + maxRightBorderSum); return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum); } private static int max3(int a, int b, int c) { return Math.max(Math.max(a, b), c); } public static int maxSubSum4(int[] a) { int maxSum = 0; int thisSum = 0; for (int j = 0; j < a.length; j++) { thisSum += a[j]; if (thisSum > maxSum) { maxSum = thisSum; } else if (thisSum < 0) { thisSum = 0; } } return maxSum; } } 运行结果为 ------maxSubSum1-------- a[0] -->-2 a[0] a[1] -->9 a[0] a[1] a[2] -->5 a[0] a[1] a[2] a[3] -->18 a[0] a[1] a[2] a[3] a[4] -->13 a[0] a[1] a[2] a[3] a[4] a[5] -->11 a[1] -->11 a[1] a[2] -->7 a[1] a[2] a[3] -->20 a[1] a[2] a[3] a[4] -->15 a[1] a[2] a[3] a[4] a[5] -->13 a[2] -->-4 a[2] a[3] -->9 a[2] a[3] a[4] -->4 a[2] a[3] a[4] a[5] -->2 a[3] -->13 a[3] a[4] -->8 a[3] a[4] a[5] -->6 a[4] -->-5 a[4] a[5] -->-7 a[5] -->-2 1489143623437--->1489143623437 ------maxSubSum1 return-------- ------0 millis-------- maxSubSum1: 20 ------maxSubSum2-------- a[0-0] -->-2 a[0-1] -->9 a[0-2] -->5 a[0-3] -->18 a[0-4] -->13 a[0-5] -->11 a[1-1] -->11 a[1-2] -->7 a[1-3] -->20 a[1-4] -->15 a[1-5] -->13 a[2-2] -->-4 a[2-3] -->9 a[2-4] -->4 a[2-5] -->2 a[3-3] -->13 a[3-4] -->8 a[3-5] -->6 a[4-4] -->-5 a[4-5] -->-7 a[5-5] -->-2 1489143623437--->1489143623437 ------maxSubSum2 return-------- ------0 millis-------- maxSubSum2: 20 left: 0, right: 1 maxleft: 0, maxright: 11, maxLeftBorderSum: 0 maxRightBorderSum: 11 left: 0, right: 2 maxleft: 11, maxright: 0, maxLeftBorderSum: 11 maxRightBorderSum: 0 left: 3, right: 4 maxleft: 13, maxright: 0, maxLeftBorderSum: 13 maxRightBorderSum: 0 left: 3, right: 5 maxleft: 8, maxright: 0, maxLeftBorderSum: 8 maxRightBorderSum: 0 left: 0, right: 5 maxleft: 7, maxright: 13, maxLeftBorderSum: 7 maxRightBorderSum: 13 maxSubSum3: 20 maxSubSum4: 20
方法4引入了联机算法(on-line algorithm)的概念。主要特点是不需要被记忆,只顺序读入就能给出子序列问题正确答案。
