最大子序列和,最小子序列和,最小正子序列和,最大子序列乘积
来自:【数据结构与算法分析——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; }