來自:【數據結構與算法分析——C語言描述】練習2.12
有關這 4 個子序列算法的思路,都是源於 最大子序列和問題 的延伸,具體請參考 【數據結構與算法分析——C語言描述】第二章總結 算法分析 中的 “最大子序列和問題”部分。
下面是 4 個子序列算法的代碼實現。
最大子序列和
1. 窮舉法,時間復雜度O(N3)
int maxSequenceSum1(const int A[], int N) { int i, j, k, maxSum, thisSum; maxSum = 0; for (i = 0; i < N; i++) { for (j = i; j < N; j++) { thisSum = 0; for (k = i; k <= j; k++) thisSum += A[k]; if (thisSum > maxSum) maxSum = thisSum; } } return maxSum; }
2. 撤一個for,O(N2)
int maxSequenceSum2(const int A[], int N) { int i, j, maxSum, thisSum; maxSum = 0; for (i = 0; i < N; i++) { thisSum = 0; for (j = i; j < N; j++) { thisSum += A[j]; if (thisSum > maxSum) maxSum = thisSum; } } return maxSum; }
3. 分治算法,O(NlogN)
int maxSubSum(const int A[], int left, int right) { int maxLeftSum, maxRightSum; int maxLeftBorderSum, maxRightBorderSum; int leftBorderSum, rightBorderSum; int center, i; if (left == right) /*Base case*/ { if (A[left] > 0) return A[left]; else return 0; } center = (left + right) / 2; maxLeftSum = maxSubSum(A, left, center); maxRightSum = maxSubSum(A, center + 1, right); maxLeftBorderSum = 0; leftBorderSum = 0; for (i = center; i >= left; i--) { leftBorderSum += A[i]; if (leftBorderSum > maxLeftBorderSum) maxLeftBorderSum = leftBorderSum; } maxRightBorderSum = 0; rightBorderSum = 0; for (i = center + 1; i <= right; i++) { rightBorderSum += A[i]; if (rightBorderSum > maxRightBorderSum) maxRightBorderSum = rightBorderSum; } return max(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum); } int maxSequenceSum3(const int A[], int N) { return maxSubSum(A, 0, N - 1); }
4. 聯機算法,O(N)
int maxSequenceSum4(const int A[], int N) { int i, maxSum, thisSum; maxSum = 0; thisSum = 0; for (i = 0; i < N; i++) { thisSum += A[i]; if (thisSum> maxSum) maxSum = thisSum; else if (thisSum < 0) thisSum = 0; } return maxSum; }
下面,我仍然采用更優的聯機算法來求解最小子序列和、最小正子序列和、以及最大子序列乘積。
最小子序列和
int minSequenceSum(const int A[],int N) { int minSum, thisSum, i; minSum = 0; thisSum = 0; for (i = 0; i < N; i++) { thisSum += A[i];; if (thisSum < minSum) minSum = thisSum; else if (thisSum>0) thisSum = 0; } return minSum; }
最小正子序列和
int minPositiveSubSum(const int A[], int N) { int minSum, thisSum, i; minSum = 0x7FFFFFFF; thisSum = 0; for (i = 0; i < N; i++) { thisSum += A[i]; if (thisSum < minSum && thisSum > 0) minSum = thisSum; else if (thisSum < 0) thisSum = 0; } return minSum; }
最大子序列乘積
int maxPositiveSubMul(const int A[], int N) { int maxMul, thisMul, i; maxMul = 1; thisMul = 1; for (i = 0; i < N; i++) { thisMul *= A[i]; if (thisMul > maxMul) maxMul = thisMul; } return maxMul; }