最大連續子序列之和
給定整數A1,A2,A3,...,An(可能爲負整數),求最大的連續子序列和。如果所有數是負數,則和是零。
例如:{-2,11,-4,13,-5,2} 答案是20,序列項從第2項到第4項。
此題很多解法,現討論4種解法。第1種是簡單窮舉搜索算法,效率特別低。第2種算法是第一種算法的改進,簡單觀察完成。第3種算法非常高效,但不簡單,複雜度是線性的O(n)。第4種算法複雜度是O(N log N)
- public 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 + 1; i <= right; i++)// 計算包括中心邊界的右最大和
- {
- rightBorderSum += a[i];
- if (rightBorderSum > maxRightBorderSum)
- maxRightBorderSum = rightBorderSum;
- }
- return max3(maxLeftSum, maxRightSum, maxLeftBorderSum
- + maxRightBorderSum);
- }
- public static int max3(int maxLeftSum, int maxRightSum, int maxSum)//計算3個數最大的
- {
- return maxLeftSum > maxRightSum ? (maxLeftSum > maxSum ? maxLeftSum
- : maxSum) : (maxRightSum > maxSum ? maxRightSum : maxSum);
- }
- public static int maxSubsequenceSum(int[] a)
- {
- return a.length > 0 ? maxSumRec(a, 0, a.length - 1) : 0;
- }