[算法导论&python学习] 求最大子数组(分治法)

运行时间为O(n^2)

def find_max_crossing_subarray(a, p, mid, r):  # 数组名,最小下标,中间下标,末尾下标
    left_sum = -9999  # -float("inf")
    sum = 0
    left_max_index = 0
    for i in range(mid, p-1, -1):  # range默认为(,,1)
        sum += a[i]
        if left_sum < sum:
            left_sum = sum
            left_max_index = i

    right_sum = -9999  # -float("inf")
    sum = 0
    right_max_index = 0
    for j in range(mid+1, r+1):
        sum += a[j]
        if right_sum < sum:
            right_sum = sum
            right_max_index = j

    return (left_max_index, right_max_index, left_sum+right_sum)


def find_max_array(a, p, r):
    if p == r:
        return (p, r, a[p])
    else:
        mid = int((p+r)/2)
        (left_low_index, left_high_index, left_sum) = find_max_array(a, p, mid)
        (right_low_index, right_high_index, right_sum) = find_max_array(a, mid+1, r)
        (cross_low_index, cross_high_index,cross_sum) = find_max_crossing_subarray(a, p, mid, r)

        if left_sum >= right_sum and left_sum >= cross_sum:
            return (left_low_index, left_high_index, left_sum)

        elif right_sum >= left_sum and right_sum >= cross_sum:
            return (right_low_index, right_high_index, right_sum)
        else:
            return (cross_low_index, cross_high_index, cross_sum)


a = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]
c = [13, -3, -25, 20, -3, 16]
b = find_max_array(c, 0, len(c)-1)
print(b)

练习4.1-5:
已知a[1…j]的最大子数组,基于以下性质将解扩展为a[1…j+1]的最大子数组:a[1…j+1]的最大子数组要么是a[1…j]的最大子数组,要么是某个子数组ai…j+1。在线性时间内找出形如a[i…j+1]的最大子数组

代码如下

def solution_expand(a, value, max_subarray):  # 数组,添加值,a[1...j]的最大子数组
    a.append(value)
    sum = -float('inf')
    a_sum = 0
    for i in range(len(a)-1, -1, -1):
        a_sum += a[i]
        if(a_sum > sum):
            sum = a_sum
            max_index = i

    if(sum > max_subarray[2]):
        return (max_index, len(a)-1, sum)
    else:
        return max_subarray

遍历了拓展以后的数组,时间复杂度为Θ(n).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值