您的位置:首页 > 其它

最大子列和问题

2016-03-20 11:43 387 查看
一. 给定N个整数的序列{A1, A2,...,An},求函数

的最大值


1. 算法一:

<span style="font-size:14px;">int MaxSubseqSum1(int A[], int N)
{
int ThisSum, MaxSum = 0;
int i, j, k;
for(i = 0; i < N; i++)/* i是子列左端位置 */
{
for(j = i; j < N; j++)/* j是子列右端位置 */
{
ThisSum	= 0;/* ThisSum是从A[i]到A[j]的子列和 */
for(k = i; k <= j; k++)
{
ThisSum += A[k];
}
if(ThisSum > MaxSum)/*如果刚得到的这个子列和更大*/
{
MaxSum = ThisSum;/* 则更新结果 */
}
}/* j循环结束 */
}/* i循环结束 */
return MaxSum;
}</span>
时间复杂度:



上面这个算法是以下面方式累加的:

1) 当i = 0 时候,











.....



当i = 1时候,





....



2. 算法二:

对于相同的i,不同的j,只要在j - 1次循环的基础上累加1项即可。



<span style="font-size:14px;">int MaxSubseqSum2(int A[], int N)
{
int ThisSum, MaxSum = 0;
int i, j;
for(i = 0; i < N; i++)/* i是子列左端位置 */
{
ThisSum	= 0;/* ThisSum是从A[i]到A[j]的子列和 */
for(j = i; j < N; j++)/* j是子列右端位置 */
{
ThisSum += A[k];
/*对于相同的i,不同的j,只要在j-1次循环的基础上累加1项即可*/
if(ThisSum > MaxSum)/*如果刚得到的这个子列和更大*/
{
MaxSum = ThisSum;/* 则更新结果 */
}
}/* j循环结束 */
}/* i循环结束 */
return MaxSum;
}</span>


时间复杂度:


3. 第三种算法:分而治之

把数组一份为二,采用递归的方法去解决左右两边的问题,

递归的解决左边的问题,会得到左边的最大子列和

递归的解决右边的问题,会得到右边的最大子列和
跨越边界的最大子列和,把这三个结果找到,我最后的结果一定是这三个最大的
开始是分,最后的合成是治



 


 






如何求跨越子列和:

从中间开始,往左边扫描,然后往右边扫描。没个原始都会被扫描一次。

从中间线开始往左逐个累加,然后找到从中间左边第一个开始累加的最大值,

然后从中间往右逐个累加,然后找到从间接线右边第一个开始累加的最大值。

然后把左右两边给合并起来,得出的结果就是跨越子列和的最大值。


时间复杂度:



4. 算法四:在线处理



















































最大值就是:7
int MaxSubseqSum4(int A[], int N)
{
int ThisSum, MaxSum;
int i;
ThisSum = MaxSum = 0;
for(i = 0; i < N; i++)
{
This+=A[i];/*向右累加*/
if(ThisSum > MaxSum)
{
MaxSum = ThisSum;/*发现更大和则更新当前结果*/
}
else if(ThisSum < 0)/* 如果当前子列和为负 */
{
ThisSum = 0;/* 则不可能使后面的部分和增大,抛弃之 */
}
}
return MaxSum;
}


时间复杂度:


“在线”的意思是指每输入一个数据就进行即时处理,在任何一个地方中止输入,算法都能正确给出当前的解。
5. 运行时间比较:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  最大子列和