求最大子列和问题(浙江大学数据结构)

问题陈述:

  给定N个整数的序列{A1, A2, ... , AN},求函数ƒ(i, j) = max{0, Ai + Ai+1 + ... + Aj}(1<=i<j<=N)的最大值。

 

问题分析:

  求给定数列的最大子列和。

方法一:暴力求解  :遍历每个子序列。时间复杂度T(N)=N3。

int MaxSubseqSum1(int A[],int n)
{
int i,j,k;
int ThisSum,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;
}

方法二:对方法一的优化,即每个子序列的和是前一个子序列加上后一个的和。时间复杂度T(N)=N2。

int MaxSubseqSum2(int A[],int n)
{
int i,j,k;
int ThisSum,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;
}

方法三:分治法


时间复杂度:T(N)=2T(N/2)+CN

= 22 * T(N/22) + c2N

   = 2* T(N/2k) + ckN 其中 N/2k = 1

        = N * T(1) + cNlog2N

   = O(NlogN)

//第三种,分治法 
int Max(int A,int B,int C)
{
if(A>B&&A>C)
return A;
else
if(B>A&&B>C)
return B;
else
return C;
 } 
int PartSum(int A[],int left,int right)
{
int center,i;
int MaxLeftSum,MaxRightSum;
int LeftBorderSum=0,RightBorderSum=0;
int MaxLeftBorderSum=0,MaxRightBorderSum=0;
center=(left+right)/2;

//递归终止条件
if(left==right)
{
if(A[left]>0)
return A[left];
else
return 0;
}

//递归求左右两边的最大值
MaxLeftSum=PartSum(A,left,center);
MaxRightSum=PartSum(A,center+1,right);

//求经过center的最大子列值
for(i=center;i>=left;i--)
{
LeftBorderSum+=A[i];
if(LeftBorderSum>MaxLeftBorderSum)
MaxLeftBorderSum=LeftBorderSum;
}
for(i=center+1;i<=right;i++)
{
RightBorderSum+=A[i];
if(RightBorderSum>MaxRightBorderSum)
MaxRightBorderSum=RightBorderSum;
}

//返回分治部分的最大值
return Max(MaxLeftSum,MaxRightSum,(MaxLeftBorderSum+MaxRightBorderSum));

int MaxSubseqSum3(int A[],int n)
{
return PartSum(A,0,n-1);
}

第四种(最简单):在线处理(每输入一个数据就进行即时处理),时间复杂度:T(N)=O(N)。

int MaxSubseqSum4(int A[],int n)
{
int ThisSum,MaxSum;
int i;
ThisSum=MaxSum=0;
for(i=0;i<n;i++)
{
ThisSum+=A[i];
if(ThisSum>MaxSum)
MaxSum=ThisSum;
else
if(ThisSum<0)
ThisSum=0;
}
return MaxSum;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值