/**
* author: bbird_gl
* date: 2019/6/26
* description: 求给定整数序列的最大子序列,为了方便起见,如果所有整数均为负数,则最大子序列和为0
*/
//方法一:三层循环,时间复杂度O(n^3)
int MaxSubsequenceSum(const int A[], int N)
{
int ThisNum, MaxNum, i, j, k;
MaxNum = 0;
for (i = 0; i < N; i++) {
for (j = i; j < N; j++) {
ThisNum = 0;
for (k = i; k <= j; k++) {
ThisNum += A[k];
if (MaxNum < ThisNum)
MaxNum = ThisNum;
}
}
}
return MaxNum;
}
//方法二:二层循环,时间复杂度O(n^2)
int MaxSubsequenceSum(const int A[], int N)
{
int ThisNum, MaxNum, i, j;
MaxNum = 0;
for (i = 0; i < N; i++) {
ThisNum = 0;
for (j = i; j < N; j++) {
ThisNum += A[j];
if (MaxNum < ThisNum)
MaxNum = ThisNum;
}
}
return MaxNum;
}
//方法三:使用递归,时间复杂度O(n*logn)
//该方法采用“分治”策略,最大子序列和可能在三处出现,即出现在输入数据的前半部分或者输入数据的后半部分
//或者跨越输入数据的中部
int MAX3(int x, int y, int z)
{
int max = x;
if (y > max)
max = y;
if (z > max)
max = z;
return max;
}
static int MaxSubSum(const int A[], int left, int right)
{
int maxLeftSum, maxRightSum;
int maxLeftBorderSum, maxRightBorderSum;
int leftBorderSum, rightBorderSum;
int center, i;
if (left == right)
{
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);
leftBorderSum = 0;
maxLeftBorderSum = 0;
for (i = center; i >= left; i--) {
leftBorderSum += A[i];
if (leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
rightBorderSum = 0;
maxRightBorderSum = 0;
for (i = center + 1; i <= right; i++) {
rightBorderSum += A[i];
if (rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
return MAX3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);
}
int MaxSubsequenceSum(const int A[], int N)
{
return MaxSubSum(A, 0, N - 1);
}
//方法四:联机算法(online algorithm),时间复杂度O(n)
int MaxSubsequenceSum(const int A[], int N)
{
int ThisNum, MaxNum, i;
ThisNum = 0;
MaxNum = 0;
for (i = 0; i < N; i++) {
ThisNum += A[i];
if (ThisNum > MaxNum)
MaxNum = ThisNum;
else if (ThisNum < 0)
ThisNum = 0;
}
return MaxNum;
}