您的位置:首页 > 其它

最大子序列问题及其求解

2012-02-28 14:29 357 查看
问题说明:给定整数

(可能有负数),求

的最大值(为方便起见,如果所有整数均为负数,则最大子序列和为
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: