【数据结构与算法】最大子列和问题

本文探讨了四种不同方法来解决最大连续子序列和的问题,包括暴力求解、优化求和、分治策略及在线处理,详细介绍了每种方法的实现思路与复杂度。

问题:给定N个整数序列,{A1,A2,…,An},求该序列中存在的最大的连续n个整数和。

分析:

    方法1:最自然的方法是设置子列和的左端索引i和右端索引j,然后通过遍历的方法找出最大的子列和,其中最简单的数组求和也是遍历相加,因此将会有三层循环,计算复杂度为O(N^3)

代码为:

int MaxSum1(int a[],int N){//暴力求解,复杂度O(N^3) 
	int i=0;
	int j=0;
	int k=0;
	int MaxSum=0;
	int sum=0;
	for(i=0;i<N;i++)
	{
		for(j=i;j<N;j++)
		{
			for(k=i;k<=j;k++)
			{
			sum+=a[k];
			if (MaxSum<sum) MaxSum=sum;	
			}
			sum=0;
		}
	}
	return MaxSum;
}

方法2:注意到在求子列和时,是依次推移进行的,因此可以讲方法1中的求和循环,修改为依次叠加,前索引1次迭代完成后要做一次清0;计算复杂度下降为O(N^2);

int MaxSum2(int a[],int N){//优化,复杂度O(N^2) 
	int i=0,j=0,Sum=0,MaxSum;
	
	for(i=0;i<N;i++){
		for(j=i;j<N;j++){
			Sum=Sum+a[j];
			
		if(MaxSum<Sum) MaxSum=Sum;
		 
		}
		Sum=0;
	}
	return MaxSum;
	
}

方法3:分而治之

将数据一分为2,最大子列和会有三种情况:在左边,在右边,中间线往两边。前两者可以才有递归实现,中间往两边可以另外考察。最后返回这三个数据中最大的一项;计算复杂度为NlogN

int Max3(int A,int B,int C){
//	return A>B?A>C?A:C:B>C?B:C;
	return A > B ? A > C ? A : C : B > C ? B : C;
}

int MaxSum3(int a[],int left,int right){
	
	int MaxSumLeft=0,MaxSumRight=0;
	int i;
	int MaxBroLeft=0,MaxBroRight;
	int BroLeftSum=0,BroRightSum=0; 
	int MaxBro;
	
	int center=(left+right)/2;//中间位置 
	
	if (left==right)//迭代停止条件 
	{
		if (a[left]>0) return a[left];
		else return 0;
	}
	
	MaxSumLeft=MaxSum3(a,left,center);//左最大子列和 
	MaxSumRight=MaxSum3(a,center+1,right);//右最大子列和
	
	 
	//向左搜索
	for (i=center;i>=left;i--) 
	{
		BroLeftSum+=a[i];
		if (MaxBroLeft<BroLeftSum)
			MaxBroLeft=BroLeftSum;
		
	}
	
	//向右搜索
	for (i=center;i<=right;i++)
	{
		BroRightSum+=a[i];
		if (MaxBroRight<BroRightSum)
			MaxBroRight=BroRightSum;
		
	 } 
	
	MaxBro=MaxBroRight+MaxBroLeft-a[center];
	
	return (Max3(MaxBro,MaxSumLeft,MaxSumRight));
	
}

方法4:在线处理

我们想象数据流依次进入系统,每进入一个数据,就做一次分析,分析发现,若新进入的数据,使得最大和边为负数,则该数不可能作为一个新子列的前索引,同时上一索引点结束,只保留上一状态的最大子列和,之后再对后续进入的数据分析。

计算复杂度为O(N)

int MaxSum4(int a[],int N){//在线,计算复杂度O(N) 
	int i=0;
	int Sum=0,MaxSum=0;
	for (i=0;i<N;i++)
	{
		Sum+=a[i];
		
		if (MaxSum<Sum)
			MaxSum=Sum;
		if (Sum<0) Sum=0;
	}

return MaxSum;


} 

主函数:

int main(int argc, char *argv[]) {
	
	int a[8]={4,-3,5,-2,-1,2,6,-2};
	int Max=0;
	int N=8;
	Max=MaxSum4(a,N);
	//Max=MaxSum3(a,0,N-1);
	printf("MaxSum:%d",Max);
	
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值