最大子序列求解

什么是最大子序列?

数据存在一个list中,和最大的子list就是最大子序列

定义:data[1,-2,5,4,-4],寒无疑问,最大子序列就是[5,4] ,sum=9

求解方法:

  一、枚举,这是暴力算法,简单的讲就是枚举全部子序列,通过比较,然后求出最大的子序列,算法复杂为O(N^3)

def Max_son(data):
	N = len(data)
	max_son = 0
	for left in range(0,N-1):
		for right in range(left,N-1):
			This_son = 0
			for key in range(left,right):
				This_son += data[key]
			if max_son < This_son:
				max_son = This_son
	return max_son

二、枚举改进。从第一个算法可知,第一层循环,循环的是子序列的左边界:第二层循环,循环的是子序列的右边界:第三层循环,循环的是当前子序列的每个元素。每次循环完当前子序列后,当前子序列和清零,这就造成计算浪费,因为,下一个子序列,不过是当前子序列的右边界向后一位,也就是增加一个元素,so,可以删除第三次循环,保留当前子序列的和。算法复杂度为O(N^2)

def Max_son(data):
	N = len(data)
	max_son = 0
	for left in range(0,N-1):
		This_son = 0
		for right in range(left,N-1):
			This_son += data[right]
			if max_son < This_son:
				max_son = This_son
	return max_son


三、分治。分就是将原问题的规模每次缩小,治就是对当原问题缩小到一定规模的时候,直接求解,再合并子规模的解,就是原问题的解。通常,将分治和递归联系在一起,递归有利于问题的缩小与子答案的合并。对于用分治求解最大子序列,对于规模的虽小,显然是缩减list的长度,缩减到什么规模合适呢?缩减到一个元素就是最合适的,缩小的思想和中学用隔板法求解排列组合问题相似。至于求解,特别注意解的合并,需要计算包含两个子序列的边界的和,这样才能最终合并为原序列的解。至于递归,需包含两大要素,可变递归因子和出口,这就契合的分治的思想,可变递归因子对应缩小规模,出口就是最小问题的解,也就是仅仅只有一个元素的时候的子序列。算法复杂度为O(NlogN)

def Max_son(left,right,data):
	if left == right:
		if data[left] > 0:
			return data[left]
		else:
			return 0
	center = (left + right)//2
	Max_son_L=Max_son(left,center,data)
	Max_son_R=Max_son(center+1,right,data)
	
	Max_son_of_left = Son_of_left = 0
	for x in range(center-1,left-1,-1):
		Son_of_left += data[x]
		if Max_son_of_left < Son_of_left:
			Max_son_of_left = Son_of_left
			
	Max_son_of_right = Son_of_right = 0
	for i in range(center,right+1):
		Son_of_right += data[i]
		if Max_son_of_right < Son_of_right:
			Max_son_of_right = Son_of_right
	
	return max(Max_son_L,Max_son_R,Max_son_of_left+Max_son_of_right)

四、实时比较。我也不知道为这个算法取什么名字,就随便DIY了一个。这个算法可以完爆前面的算法,当然是就本题而言。前面的算法实际上都是为了比较各个子序列的和,然后求出最大值。注意要求,是求出最大子序列的和,根据第三个分治算法,每个序列都是由它的子序列构成,我们叫它为母序列,那么当一个母序列的子序列变成负数的时候,这个序列肯定就没必要再加到其母序列中了。So,我们从原序列的左边开始叠加,每加一个元素就是更新一个母序列,当当前母序列为负数时,下一个母序列就没必要再加这个序列了,再从当前元素重新叠加母序列。算法复杂度为O(N)

def Max_son(data):
	N = len(data)
	max_son = This_son = 0
	for left in range(0,N-1):
			This_son += data[left]
			if max_son < This_son:
				max_son = This_son
			elif This_son < 0:
				This_son = 0
	return max_son

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值