来自:【数据结构与算法分析——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;
}