注意:为方便起见,如果所有整数均为负数,则最大子序列和为0
解法一:
穷举法,时间复杂度为O(N3)
int MaxSubsequenceSum(const int A[], int N) {
int MaxSum = 0;
for(int i = 0; i < N; i++)
for(int j = i; j < N; j++) {
int ThisSum = 0;
for(int k = i; k <= j; k++)
ThisSum += A[k];
if(ThisSum > MaxSum)
MaxSum = ThisSum;
}
return MaxSum;
}
解法二:
在解法1的基础上进行适当的修改可使时间复杂度成为O(N2)
int MaxSubSequenceSum(const int A[], int N) {
int MaxSum = 0;
for(int i = 0; i < N; i++) {
int ThisSum = 0;
for(int j = i; j < N; j++) {
ThisSum += A[j];
if(ThisSum > MaxSum)
MaxSum = ThisSum;
}
return MaxSum;
}
解法三:
分析:在此题中,最大子序列和可能在三处出现。或者是整个出现在输入数组的左半部,或者是整个出现在右半部,或者跨越输入数组的中部。前两种情况可以递归求解。第三种情况的最大和可以通过求出前半部分的做大和以及后半部分的最大和而得到。时间复杂度为O(NlogN)。
int MaxSubSum(const int A[], int left, int right) {
if(left == right)
return A[left]>0 ? A[left] : 0;
int mid = (left + right) / 2;
int MaxLeftSum = MaxSubSum(A, left, mid);
int MaxRightSum = MaxSubSum(A, mid+1, right);
int LBorderSum = 0, RBorderSum = 0;
int MLBorderSum = 0, MRBorderSum = 0;
for(int i = mid; i >= left; i--) {
LBorderSum += A[i];
if(LBorderSum > MLBorderSum)
MLBorderSum = LBorderSum;
}
for(int i = mid+1; i <= right; i++) {
RBorderSum += A[i];
if(RBorderSum > MRBorderSum)
MRBorderSum = RBorderSum;
}
return max(max(MaxLeftSum, MaxRightSum), MLBorderSum + MRBorderSum);
}
int MaxSubsequenceSum(const int A[], int N) {
return MaxSubSum(A, 0, N-1);
}
解法四:
int MaxSubsequenceSum(const int A[], int N) {
int ThisSum, MaxSum;
for(int i = 0; i < N; i++) {
ThisSum += A[i];
if(ThisSum > MaxSum)
MaxSum = ThisSum;
else if(ThisSum < 0)
ThisSum = 0;
}
return MaxSum;
}
该算法时间复杂度为O(N)。