最大子序列和的4种解法的时间复杂度的分析---C语言

算法一:穷举—繁

#include<stdio.h>
//求最大值序列和一 
int main()
{
	int sum,num;
	int n,i,j,k;
	scanf("%d",&n);//输入序列总数
	int a[n];
	for(i=0;i<n;i++) 
	{
		scanf("%d",&a[i]);//输入序列 
	}
	sum=0;//最大子序列和置0 
	for(i=0;i<n;i++)
	{
		for(j=i;j<n;j++)
		{
			num=0;//临时子序列和比较完归0 
			for(k=i;k<=j;k++)//用三层for循环来遍历所有序列和的可能 
			{
				num+=a[k];//求出所有序列和 
			}
			if(num>sum)
			{
				sum=num;//比较得出最大值 
			}
		}
	}
	
	printf("%d",sum);//输出最大值 
	
	return 0;
}

时间复杂度:第一个for是n,第二个for代表n个(j-i)也就是n*(j-i),(j-i)大概可以估算为n/2,所以第二个for是 二分之n的平方(n^2/2) ,所以第三个for就是(n^2/2)个(j-i),此时由上可得这三个for的复杂度为 An的三次方(An^3) A为系数,可以不计,则为n^3。(具体推导方式参考《数据结构与算法分析—C语言描述》21页。

算法二:穷举—简

#include<stdio.h>
//求最大值序列和二 
int main()
{
	int sum,num;
	int n,i,j,k;
	scanf("%d",&n);//输入序列总数
	int a[n];
	for(i=0;i<n;i++) 
	{
		scanf("%d",&a[i]);//输入序列 
	}
	sum=0;//最大子序列和置0 
	for(i=0;i<n;i++)
	{
		num=0;//临时子序列和比较完归0 
		for(j=i;j<n;j++)//用二层for循环来遍历所有序列和的可能 
		{
			num+=a[j];//求出所有序列和 
			if(num>sum)
			{
				sum=num;//比较得出最大值
			}
		} 
	}
	
	printf("%d",sum);//输出最大值 
	
	return 0;
}

时间复杂度:,可以明显看出与算法一相比的区别,所以类比于算法一,n^2。

算法三—分而治之

#include<stdio.h>
//求最大子序列和三—分而治之
int max3(int a,int b,int c)
{
	return ((a>b?a:b)>c)?(a>b?a:b):c;//用条件运算符来比较 
}//求三个数的最大值 
int maxsum(int a[],int left, int right)
{
	int center,i;
	int leftmaxsum,rightmaxsum;
	int leftborder=0,rightborder=0; 
	int leftbordermax=0,rightbordermax=0;
	
	if(left==right)
	{
		if(a[left]>=0)
		{
			return a[left];
		}else{
			return 0;
		}
	}//如果只有一个元素,正数不变,负数置零 
    
	center=(left+right)/2;//取中间序号 
	leftmaxsum=maxsum(a,left,center);//递归逐渐向左 
	rightmaxsum=maxsum(a,center+1,right);//递归逐渐向右 
	
	for(i=center;i>=left;i--)
	{
		leftborder+=a[i];
		if(leftborder>leftbordermax)
		{
			leftbordermax=leftborder;
		}
	}//求出左边靠右的最大子序列和 
	
	for(i=center+1;i<=right;i++)
	{
		rightborder+=a[i];
		if(rightborder>rightbordermax)
		{
			rightbordermax=rightborder;
		}
	}//求出右边靠左的最大子序列和
	
	return max3(leftmaxsum,rightmaxsum,rightbordermax+leftbordermax);//调用max3函数 
}//递归,层层深入。二分,步步为营。  
int main()
{
	int n,i;
	scanf("%d",&n);//输入序列总数
	int a[n];
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);//输入序列 
	}
	
	printf("%d",maxsum(a,0,n-1));//,调用maxsum函数,输出最大子序列和 
	
	return 0;
} 

时间复杂度:NlnN(具体推导方式参考《数据结构与算法分析—C语言描述》24页。
算法四—联机算法

#include<stdio.h>
//求最大子序列和4,在线处理
int main()
{
	int sum,num;
	int n,i;
	scanf("%d",&n);//输入序列总数
	int a[n];
	for(i=0;i<n;i++) 
	{
		scanf("%d",&a[i]);//输入序列 
	}
	sum=num=0;//置0
	
	for(i=0;i<n;i++)
	{
		num+=a[i];
		if(num>sum)
		{
			sum=num;//及时存放 
		}else if(num<0)
		{
			num=0;//负则归0 
		}
	} 
	
	return 0;
} 

时间复杂度:N (◎﹏◎)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值