算法:寻找maximum subarray

《算法导论》一书中演示分治算法的第二个例子,第一个例子是递归排序,较为简单。寻找maximum subarray稍微复杂点。

题目是这样的:给定序列x = [1, -4, 4, 4, 5, -3, -4, 9, 6 - 4, 6, 4, 3, -5];寻找一个连续的子序列,使得其和是最大。

这个题目有意义的地方在于,序列X的元素有正有负。

思路很简单,把序列分为相同的两部分A和B,在其内寻找maximum subarray,那么maximum subarray有可能在A中,也有可能在B中,也有可能横跨A和B。

所以,一、递归地在A,B中寻找最大子序列;二、在序列X中寻找横跨中间点的maximum subarray;

最后,比较三者,哪个打,结果就是哪个喽。

代码如下:

在序列X中寻找横跨中间点的maximum subarray

def findmaxcrosssubarr(arr, low, mid, high):
    lefmax = -10000
    sum_l = 0
    i = mid
    index_l=mid
    index_r=mid
    while (i > low):
        sum_l += arr[i]
        if sum_l > lefmax:
            lefmax = sum_l
            index_l = i
        i -= 1
    rightmax = -10000
    sum_r = 0
    j = mid + 1
    while (j < high):
        sum_r += arr[j]
        if sum_r > rightmax:
            rightmax = sum_r
            index_r = j
        j += 1
    return lefmax + rightmax, index_l, index_r

递归地寻找maximum subarray

def maxsubarr(arr, low, high):
    if high-low < 1:
        return arr[low], low, high
    mid = (high+low)/2
    value_l, low_l, high_l = maxsubarr(arr, low, mid)
    value_r, low_r, high_r = maxsubarr(arr, mid+1, high)
    value_m, low_m, high_m = findmaxcrosssubarr(arr, low, mid, high)
    maxvalue = max(value_l, value_m, value_r)
    if maxvalue==value_l:
        return value_l, low_l ,high_l
    if maxvalue==value_r:
        return value_r, low_r, high_r
    if maxvalue==value_m:
        return value_m, low_m, high_m

感想:递归解决问题的几个考虑的点:1、做好问题的分解,形成递归(就是说子问题和原问题是同类型的)后,就可以假设可以解决了,最多就是把初始情况解决了;2、子问题合并回原问题比较有技巧性,需要多思考。

当然,也可以使用暴力解法,遍历所有可能的情况,通过比大小,找出答案。

def brutemaxsub(arr):
    m=-10000
    s,t=0,0
    for i in range(len(arr)):
        j=i
        maxj=0
        while j<len(arr):
            maxj+=arr[j]
            if maxj>m:
                m=maxj
                s=i
                t=j
            j+=1
    return m,s,t

当然啦,这个问题也可以在线性时间内解决。

代码如下,有点绕。

def maxsub(arr):
    m=m1=arr[0]
    s,t=s1,t1=0,0
    i = 1
    while i<len(arr):
        m1+=arr[i]
        if m1>m:
            s=s1
            t=t1=i
            m=m1
        if m1<0:
            s1=i+1
            t1=i + 1
            m1=0
        i+=1
    return m,s,t
原文地址:https://www.cnblogs.com/wrajj/p/5733286.html