本文程序介绍求最大子序列和的四种经典方法:
//四种算法
//算法1,穷举,时间复杂度为 O(N^3)
int MaxSubsequenceSum1(const int A[], int N)
{
int ThisSum, MaxSum, i, j, k;
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,简化穷举,时间复杂度为 O(N^2)
int MaxSubsequenceSum2(const int A[], int N)
{
int ThisSum, MaxSum, i, j;
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(N log(N))
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);
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;
}
}
int MaxPart1 = MaxLeftSum > MaxRightSum ? MaxLeftSum : MaxRightSum;
int MaxPart2 = MaxLeftBorderSum + MaxRightBorderSum;
return MaxPart1 > MaxPart2 ? MaxPart1 : MaxPart2;
}
int MaxSubsequenceSum3(const int A[], int N)
{
return MaxSubSum(A, 0, N - 1);
}
//算法4,联机算法,时间复杂度为 O(N)
int MaxSubsequenceSum4(const int A[], int N)
{
int ThisSum, MaxSum, i;
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;
}
测试代码:
#include <iostream>
#include <time.h>
#include <math.h>
#include <windows.h>
using namespace std;
int main()
{
srand((int)time(0));
int N = 10000;
int *A = new int[N];
for (int i = 0; i < N; i++)
{
A[i] = (rand() % 20)*pow(double(-1), double(rand() % 2));
printf("%5d", A[i]);
if (i%10==9)
{
cout << endl;
}
}
SYSTEMTIME time_begin, time_end;
int MaxSum = 0;
GetLocalTime(&time_begin);
MaxSum = MaxSubsequenceSum1(A,N);
GetLocalTime(&time_end);
printf("算法1结果为:%d ,耗时:%d毫秒\n", MaxSum
,time_end.wMilliseconds - time_begin.wMilliseconds
+ 1000 * (time_end.wSecond - time_begin.wSecond
+ 60 * (time_end.wMinute - time_begin.wMinute)));
MaxSum = 0;
GetLocalTime(&time_begin);
MaxSum = MaxSubsequenceSum2(A, N);
GetLocalTime(&time_end);
printf("算法2结果为:%d ,耗时:%d毫秒\n", MaxSum
, time_end.wMilliseconds - time_begin.wMilliseconds
+ 1000 * (time_end.wSecond - time_begin.wSecond
+ 60 * (time_end.wMinute - time_begin.wMinute)));
MaxSum = 0;
GetLocalTime(&time_begin);
MaxSum = MaxSubsequenceSum3(A, N);
GetLocalTime(&time_end);
printf("算法3结果为:%d ,耗时:%d毫秒\n", MaxSum
, time_end.wMilliseconds - time_begin.wMilliseconds
+ 1000 * (time_end.wSecond - time_begin.wSecond
+ 60 * (time_end.wMinute - time_begin.wMinute)));
MaxSum = 0;
GetLocalTime(&time_begin);
MaxSum = MaxSubsequenceSum4(A, N);
GetLocalTime(&time_end);
printf("算法4结果为:%d ,耗时:%d毫秒\n", MaxSum
, time_end.wMilliseconds - time_begin.wMilliseconds
+ 1000 * (time_end.wSecond - time_begin.wSecond
+ 60 * (time_end.wMinute - time_begin.wMinute)));
return 0;
}