最大子序列问题及其求解
问题说明:给定整数(可能有负数),求的最大值(为方便起见,如果所有整数均为负数,则最大子序列和为 0 )。
三种实现方法:
方法一:O(n^2)
template<class T> T MaxSubSequenceSum_1(const T A[], int length) { T thisSum = 0; T maxSum = 0; for(int i=0; i<length; ++i) { thisSum = 0; for(int j=i; j<length; ++j) { thisSum += A[j]; if (thisSum>maxSum) { maxSum = thisSum; } } } return maxSum; }
方法二:O(nlogn)
template<class T> T MaxSubSequenceSum_2(const T A[], int left, int right) { //最大子序列产生的三种情况:左半部分、右半部分、中间部分 if (left==right) //基准情形 { if (A[left]>0) { return A[left]; } else { return 0; } } int center = (left+right)/2; T MaxLeftSum = MaxSubSequenceSum_2(A, left, center); //左边子序列最大和 T MaxRightSum = MaxSubSequenceSum_2(A, center+1, right); //右边子序列最大和 //包含左边界的子序列最大和 T MaxLeftBorderSum =0; T LeftBorderSum = 0; for (int i=center; i>=0; --i) { LeftBorderSum += A[i]; if (LeftBorderSum>MaxLeftBorderSum) { MaxLeftBorderSum = LeftBorderSum; } } //包含右边界的子序列最大和 T MaxRightBorderSum =0; T RightBorderSum = 0; for (int i=center+1; i<=right; ++i) { RightBorderSum += A[i]; if (LeftBorderSum>MaxRightBorderSum) { MaxRightBorderSum = RightBorderSum; } } //返回最大子序列和 if (MaxLeftSum>MaxRightSum) { if (MaxLeftSum>(MaxLeftBorderSum+MaxRightBorderSum)) { return MaxLeftSum; } else { return MaxLeftBorderSum+MaxRightBorderSum; } } else { if (MaxRightSum>(MaxLeftBorderSum+MaxRightBorderSum)) { return MaxRightSum; } else { return MaxLeftBorderSum+MaxRightBorderSum; } } }
方法三:O(n)
template<class T> T MaxSubSequenceSum_3(const T A[], int length) { T thisSum = 0; T maxSum = 0; for (int i=0; i<length; ++i) { thisSum += A[i]; if (thisSum>maxSum) { maxSum = thisSum; } else if (thisSum<0) { thisSum = 0; } } return maxSum; }