分治策略求解最大子数组

分治策略就是把复杂的问题分成更小的问题来求解,求解过程中会涉及到以下三个步骤:
分解:分解步骤将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小,求解更简单。
解决:解决步骤递归地求解出子问题。如果子问题的规模足够小,则停止递归,直接求解。
合并:合并步骤将子问题的解合成原问题的解。

求解最大子数据过程中的思路是,先将数组分成两部分。那么根据最大子数组出现的位置就会有三种情况。

  1. 左侧的数组
  2. 右侧的数组
  3. 跨越中间点的数组

分解和解决
如果是前两种情况,就可以把问题分解为更小规模的情况。
如果是第三种情况,则可以直接直接结果,求解方式就是从中间想两头遍历,求出最大值时的索引值和求和,求解细节见代码。
合并
判断以上三种情况下哪一种是最大子数组,然后返回相应的索引值和求和。

python代码如下

def findCrossSubarray(A, low, high):
    # 计算左侧
    sum = 0
    left_sum = float("-inf")
    mid = (low + high)//2
    max_left = mid
    for i in range(mid, low-1, -1):
        sum += A[i]
        if sum > left_sum:
            left_sum = sum
            max_left = i

    # 计算右侧
    sum = 0
    right_sum = float("-inf")
    mid = (low + high)//2
    max_right = mid
    for j in range(mid+1, high+1):
        sum += A[j]
        if sum > left_sum:
            right_sum = sum
            max_right = j
    return max_left, max_right, left_sum + right_sum

# 设计迭代函数时,要注意认真设计函数返回值
def findMaxSubarray(A, low, high):
    if high == low:
        return low, high, A[low]
    else:
        mid = (low + high)//2
        left_low, left_high, left_sum = findMaxSubarray(A, low, mid)
        right_low, right_high, right_sum = findMaxSubarray(A, mid+1, high)
        cross_low, cross_high, cross_sum = findCrossSubarray(A, low, high)
        max_sum = max(left_sum, right_sum, cross_sum)
        if max_sum == left_sum:
            return left_low, left_high, left_sum
        elif max_sum == right_sum:
            return right_low, right_high, right_sum
        elif max_sum == cross_sum:
            return cross_low, cross_high, cross_sum

if __name__ == "__main__":
    list1 = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]
    print(findMaxSubarray(list1, 0, len(list1)-1))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值