分治法计算最大字数组(Python)

比如你获得了一个投资某个股票的机会,并且,你已经准确知道了将来几天这一只股票的相对于前一天的插值,比如为[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包含三个元素,第一个值最大字数组的值,后两个分开始开始索引和终止索引。

这个代码写完,调试成功后,有些地方自己还不是特别明白。在这儿写下来,从新整理一下思路,加深一下对递归的理解。

这个分治想法特别简单,如果不考虑返回最大字数组索引的话特别好理解,就是每一次迭代我都递归寻找单侧最大的,然后与当前跨中点的比较,返回大的。

但是如果我想新加一个返回索引的功能时,可以看到,我的返回索引的地方只有两个,是跨中点的那个函数和递归函数里面递归到字数组只有一个元素的时候。刚开始我的疑惑在于,如果只设置这一个返回索引的地方,是不是有问题呀?我的主要疑惑在于,如果出现连接怎么办,这里是我多想了,因为在每一层的每一个分支,都要运行跨中点的代码,逐层向上的跨中点代码,就是为了包括下层的连接情况。或者说这里的三种情况的划分已经把所有的情况都包括了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 00:28:01

分治法计算最大字数组(Python)的相关文章

分治法求解最大子数组问题

/*     本问题是求解最大子数组问题     普通方法的复杂度为n^2     现在尝试给出一种小于n^2的算法     当然数组中必须要有负数,不然没有意义     本例中使用分治策略 */ #include<stdio.h> #include<stdlib.h> //定义返回结构体 typedef struct result {     int left; //左索引     int right; //右索引     int sum; //最大和 }*Res; //求解包含

分治法解决最大子数组问题

利用分治法解决最大子数组问题(对给定的数组得到该数组中具有最大和的子数组) /* * 对于给定的整数数组A,求出数组中具有最大和的子数组,最大和以及左右下标 * 思路:采用分治的方法,将数组分为两部分,则有最大和的子数组共有三种情况 * 在数组左边,在数组右边,跨越数组中点 */ #include <iostream> using namespace std; //存放左右边界值以及sum值的结构体 /*特别注意结构体的使用!!!!!!!!!!!*/ struct SumBorder { in

算法题|-分治法解决最大子数组问题

分治法就是将一个复杂难解决问题拆成一些容易解决的小问题,再依次解决而最终解决整个问题 new int[] { 2, -3, 4, 67, 6 } 这样一个下标为0到4的数组,要找最大子数组,需要将其拆分成两个子数组,mid=(0+4)/2 即为0~mid的左数组和mid+1~4的右数组 最大子数组可能会出现在以下三个地方 左数组中的某个最大子数组 右数组中的某个最大子数组 以mid为界,向左找到一个最大数组,向右找到一个最大数组,将两个数组合并 第三种情况非常容易得到,通过遍历查找就可以解决,而

分治法之最大子数组问题

自己敲出来的,先把代码贴上来,晚上有时间再写总结 #include<stdio.h> #define N 10 struct Max{ int low; int high; int sum; }; int a[N]; Max Findcrossing(int* a,int low,int middle,int high); Max FindSub(int* a,int low,int high); int main() { Max m; int i; for(i=0;i<N;i++) s

python使用分治法找序列最大值

最近上算法导论课,说道分治法,回来想用python写写程序练练手,于是模仿一通写了如下的代码: __author__ = 'day' def ArrayMaxMin(Array): return max(Array) def Sort(init_Array): if len(init_Array) <= 2: print (ArrayMaxMin(init_Array)) else: init_Array=[init_Array[i:i+2] for i in range(0,len(init_

大整数乘法(分治法)

题目:输入两个大整数,用数组保存每一位数,然后用分治法计算: 思路:输入X Y,X高位用A数组保存,低位用B数组保存,Y高位用C数组保存,低位用D数组保存,则:X=A*10^(n/2)+B  Y=C*10^(n/2)+D 分治方法:X*Y=A*C*10^n+((A-B)*(D-C)+A*C+B*D)*10^(n/2)+B*D; 代码如下: #include <iostream> #include <algorithm> #include <cstring> #inclu

分治法求最大最小

1 #include<stdio.h> 2 /* 分治法计算最大值和最小值的算法程序,递归实现 */ 3 void maxmin2(int d[], int left, int right, int *max, int *min) //数组,头,尾,最大值,最小值 4 { 5 int max1, min1; 6 //递归最小时处理 7 if(left==right) { //如果只有一个数 即使最大也是最小 8 *max = d[left]; 9 *min = d[left]; 10 } el

算法笔记_003:矩阵相乘问题【分治法】

目录 1 问题描述  1.1实验题目 1.2实验目的 1.3实验要求 2 解决方案 2.1 分治法原理简述 2.2 分治法求解矩阵相乘原理 2.3 具体实现源码 2.4 运算结果截图 1 问题描述 1.1实验题目 设M1和M2是两个n×n的矩阵,设计算法计算M1×M2 的乘积. 1.2实验目的 (1)提高应用蛮力法设计算法的技能: (2)深刻理解并掌握分治法的设计思想: (3)理解这样一个观点:用蛮力法设计的算法,一般来说,经过适度的努力后,都可以对其进行改进,以提高算法的效率. 1.3实验要求

python实现分治法排序

# -*- coding: utf-8 -*- """ Created on Wed May 14 16:14:50 2014 @author: lifeix """ def merge(a, start, mid, end): if start == end: return a if mid == 0: return a temp1 = a[start:mid] m1 = len(temp1)/2 print temp1,'----',m1 n