算法第一个引子:求子数列的最大和

算法第一个引子:求子数列的最大和

一直恐惧数据结构的某大一学生终于耐不住寂寞开始了算法的预习

先从一个最简单的开始吧
众所周知 那就是 !!求一段数列的子数列的最大和 !!

这里说4种学到的方法
从最简单的说起,那就是从i到j再用循环将每一段的和都求出来
当然这种情况在数据过大的时候,电脑会罢工谁给我瓶脉动

NO.4

int FindMaxSub4(int *a, int n){
	int Max=0;
	for(int i=0;i<n;i++){
		for(int j=i;j<n;j++){
			int sub=0;
			for(int k=i;k<=j;k++){
				sub+=a[k];
				if(sub>Max) Max=sub;
			}
		}
	}
	return Max;
} 

NO.3
为了让程序快一些,
聪明的前辈想到可以不用 k 的那重循环
直接在前面求出的和的基础上,添加上后面的就可以啦~

int FindMaxSub3(int *a, int n){
	int Max = 0;
	for(int i=0;i<n;i++){
		int sub=0;
		for(int j=i;j<n;j++){
			sub+=a[j];
			if(sub>Max) Max=sub;
		}
	}
	return Max;
}

NO.2
在快一点的就是传说中的分治
这一是我从上大学以来面对黑框框这么久第一次听到这么有诗意的名字

它的原理是想将数据不断分成两半
再分别求出左半右半,以及跨过分界线的最大值
再将他们三者比较得到最终结果

int Max3(int a,int b,int c){
	return a>b?a>c?a:c:b>c?b:c;
}//用函数求出三个数的最大值

int DivideandConquer(int *a, int left, int right){
	int MaxLsum,MaxRsum;
	int MaxLBorderSum,MaxRBorderSum;
	int LeftBorderSum,RightBorderSum;
	int center,i;
	//end 递归出口
	if(left==right){
		if(a[left]>0) return a[left];
		else return 0;
	}
	//divide
	center = (left+right)/2;
	MaxLsum = DivideandConquer(a,left,center);
	MaxRsum = DivideandConquer(a,center+1,right);
	
	LeftBorderSum = 0;
	MaxLBorderSum = 0;
	for(i=center; i>=left; i--){
		LeftBorderSum+=a[i];
		if(LeftBorderSum>MaxLsum) MaxLBorderSum=LeftBorderSum;
	}
	RightBorderSum = 0;
	MaxRBorderSum = 0;
	for(i=center; i<=right; i++){
		RightBorderSum+=a[i];
		if(RightBorderSum>MaxRsum) MaxRBorderSum=RightBorderSum;
	}
	//conquer
	return Max3(MaxLsum,MaxRsum,MaxLBorderSum+MaxRBorderSum); 
}

int FindMaxSub2(int *a, int n){
	return DivideandConquer(a, 0, n-1);
}

NO.1
最后就是最棒的算法啦!
我们叫他在线求法
因为他就是从头往后读哦
其复杂度也只有n,没有可能更快啦

他在同时更新Max和范围
当sum>Max 时,更新max
当sum<0时就可以舍弃前面的所有数啦
因为比零小还不如不加呢,哼
就是这么傲娇

int FindMaxSub1(int *a, int n){
	int Max=0,num=0;
	for(int i=0;i<n;i++){
		num+=a[i];
		if(num>Max){
			Max=num;
		}
		else if(num<0){
			num=0;
		}
	}
	return Max;
}

这些就是学到的求子数列最大和的方法啦

看来数据结构还是有很大用的~

有没有引起你对数据结构的兴趣呢~

一起加油吧!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值