算法导论—分治法计算最大子数组(Python)
2015-06-30 17:47
489 查看
华电北风吹
天津大学认知计算与应用重点实验室
日期:2015/6/30
比如你获得了一个投资某个股票的机会,并且,你已经准确知道了将来几天这一只股票的相对于前一天的插值,比如为[13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7],那么就有一个问题,从那一天买入,哪一天卖出获益最大?这里就是一个最大字数组问题。
最大字数组问题:在一个数组中找出最大的非空连续子数组
常见方法,暴力求解找出所有的组合,共有C(n,2)种选择,时间复杂度Theta(n^2)
分治法求解最大字数组问题,计算复杂度theta(nlogn)
分治法求解最大字数组的思想是把每一个数组一分为二,每次考虑最大字数组所在的三种可能情况:跨中点,中点左侧,中点右侧。算法的计算量主要在于跨中点这种情况,中点单侧主要是控制划分深度,所以每一层计算复杂度是theta(n),二分以后深度为log(n),因此分治法的计算复杂度是theta(nlogn)
自己写的代码如下
代码最后返回一个tuple,tuple包含三个元素,第一个值最大字数组的值,后两个分开始开始索引和终止索引。
这个代码写完,调试成功后,有些地方自己还不是特别明白。在这儿写下来,从新整理一下思路,加深一下对递归的理解。
这个分治想法特别简单,如果不考虑返回最大字数组索引的话特别好理解,就是每一次迭代我都递归寻找单侧最大的,然后与当前跨中点的比较,返回大的。
但是如果我想新加一个返回索引的功能时,可以看到,我的返回索引的地方只有两个,是跨中点的那个函数和递归函数里面递归到字数组只有一个元素的时候。刚开始我的疑惑在于,如果只设置这一个返回索引的地方,是不是有问题呀?我的主要疑惑在于,如果出现连接怎么办,这里是我多想了,因为在每一层的每一个分支,都要运行跨中点的代码,逐层向上的跨中点代码,就是为了包括下层的连接情况。或者说这里的三种情况的划分已经把所有的情况都包括了。
天津大学认知计算与应用重点实验室
日期:2015/6/30
比如你获得了一个投资某个股票的机会,并且,你已经准确知道了将来几天这一只股票的相对于前一天的插值,比如为[13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7],那么就有一个问题,从那一天买入,哪一天卖出获益最大?这里就是一个最大字数组问题。
最大字数组问题:在一个数组中找出最大的非空连续子数组
常见方法,暴力求解找出所有的组合,共有C(n,2)种选择,时间复杂度Theta(n^2)
分治法求解最大字数组问题,计算复杂度theta(nlogn)
分治法求解最大字数组的思想是把每一个数组一分为二,每次考虑最大字数组所在的三种可能情况:跨中点,中点左侧,中点右侧。算法的计算量主要在于跨中点这种情况,中点单侧主要是控制划分深度,所以每一层计算复杂度是theta(n),二分以后深度为log(n),因此分治法的计算复杂度是theta(nlogn)
自己写的代码如下
def MaxCrossSubArray(A,low,mid,high): LeftMaxSum=A[mid] leftSum=A[mid] leftIndex=mid for i in range(mid-1,low-1,-1): leftSum=leftSum+A[i] if leftSum>LeftMaxSum: LeftMaxSum=leftSum leftIndex=i rightMaxSum=0 rightSum=0 rightIndex=mid for i in range(mid+1,high+1): rightSum+=A[i] if rightSum>rightMaxSum: rightMaxSum=rightSum rightIndex=i MaxSum=LeftMaxSum+rightMaxSum return (MaxSum,leftIndex,rightIndex) def MaxSubArray(A,low,high): if low==high: return (A[low],low,high) mid=(low+high)//2 Left=MaxSubArray(A,low,mid) Cross=MaxCrossSubArray(A,low,mid,high) Right=MaxSubArray(A,mid+1,high) List=[Left,Cross,Right] result=sorted(List,key = lambda list : list[0],reverse=True) return result[0] a=[13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7] print(MaxSubArray(a,0,len(a)-1))
代码最后返回一个tuple,tuple包含三个元素,第一个值最大字数组的值,后两个分开始开始索引和终止索引。
这个代码写完,调试成功后,有些地方自己还不是特别明白。在这儿写下来,从新整理一下思路,加深一下对递归的理解。
这个分治想法特别简单,如果不考虑返回最大字数组索引的话特别好理解,就是每一次迭代我都递归寻找单侧最大的,然后与当前跨中点的比较,返回大的。
但是如果我想新加一个返回索引的功能时,可以看到,我的返回索引的地方只有两个,是跨中点的那个函数和递归函数里面递归到字数组只有一个元素的时候。刚开始我的疑惑在于,如果只设置这一个返回索引的地方,是不是有问题呀?我的主要疑惑在于,如果出现连接怎么办,这里是我多想了,因为在每一层的每一个分支,都要运行跨中点的代码,逐层向上的跨中点代码,就是为了包括下层的连接情况。或者说这里的三种情况的划分已经把所有的情况都包括了。
相关文章推荐
- Python实现监控程序执行时间并将其写入日志的方法
- Python IDE pycharm
- python实现爬取千万淘宝商品的方法
- python简单判断序列是否为空的方法
- python检查序列seq是否含有aset中项的方法
- Python调试
- python判断一个集合是否包含了另外一个集合中所有项的方法
- python中的__init__ 、__new__、__call__等内置函数的剖析
- python过滤字符串中不属于指定集合中字符的类实例
- Python Django 开发 4 ORM
- Python学习笔记2_基础知识
- Python学习笔记1_安装使用
- python获得文件创建时间和修改时间的方法
- python 单下划线/双下划线使用总结
- python中property干什么用的?
- 北京地铁月度消费总金额计算(Python版)
- python 3 过滤股票
- python读写ini配置文件方法实例分析
- Python输出中文乱码问题
- Scrapy使用过程中的中文乱码问题