Python||二分法与动态规划求解最大子段和问题

本文介绍了两种解决最大子数组和问题的方法:一种是分治法,通过不断划分子数组并合并找到最大和;另一种是动态规划,通过构建dp数组存储每个位置的最大字段和。动态规划解法更为简洁,体现了状态转移的思想。
摘要由CSDN通过智能技术生成

题目描述

        这是一道超级经典的题目,对应的是力口上的第53题,最大子数组和。本文将会给出两种解法。一种是分治解决,一种是动态规划解决。

二分法

        解决这个问题的核心想法是将数组不断地划分为更小的子数组,直到最小的子数组只包含一个元素。然后,通过递归的方式,不断地将子数组的最大子数组和合并,直到得到整个数组的最大子数组和。这里要特别注意,要如何处理最大字段在中间的情况,笔者给出的处理思路是用两个for循环,从中点向左右两端遍历,找到包含中点的最大子数组和。

具体代码实现如下:

import random
#处理跨界子段
def max_crossing_sum(arr, left, mid, right):
    left_sum = float('-inf')
    right_sum = float('-inf')
    
    current_sum = 0
    for i in range(mid, left-1, -1):
        current_sum += arr[i]
        if current_sum > left_sum:
            left_sum = current_sum
    
    current_sum = 0
    for i in range(mid+1, right+1):
        current_sum += arr[i]
        if current_sum > right_sum:
            right_sum = current_sum
    
    return left_sum + right_sum

#二分法
def max_subarray_sum(arr, left, right):
    if left == right:
        return arr[left]
    
    mid = (left + right) // 2
    
    left_sum = max_subarray_sum(arr, left, mid)
    right_sum = max_subarray_sum(arr, mid+1, right) #这里mid加1是因为在处理左半部分已经处理过一次mid了
    cross_sum = max_crossing_sum(arr, left, mid, right)
    
    return max(left_sum, right_sum, cross_sum)

# 测试
arr1 = [4, -5, 1, 2, -1, 4, -3, 1, -2]
print("测试1 最大子段和:", max_subarray_sum(arr1, 0, len(arr1)-1))

arr2 = [random.randint(-10, 10) for _ in range(100)]
print("随机数数组:", arr2)
print("测试2 最大子段和:", max_subarray_sum(arr2, 0, len(arr2)-1))

 动态规划

        接着给出动态规划解法,笔者在看到这到题目的时候,最开始的思路就是使用动态规划求解。具体思路是,使用一个dp数组来存储最大字段和,每次将目标数组中的元素加到dp数组中,比较当前dp数组中元素和与上一个状态的dp数组中元素和大小,取字段和最大的dp数组即可。

具体代码实现如下:

def max_subarray_sum_dp(arr):
    n = len(arr)
    dp = [0] * n
    dp[0] = arr[0]
    
    for i in range(1, n):
        dp[i] = max(arr[i], dp[i-1] + arr[i])
    
    return max(dp)

# 测试
arr1 = [4, -5, 1, 2, -1, 4, -3, 1, -2]
print("测试1 最大子段和:", max_subarray_sum_dp(arr1))

arr2 = [random.randint(-10, 10) for _ in range(100)]
print("随机数数组:", arr2)
print("测试2 最大子段和:", max_subarray_sum_dp(arr2))

        动态规划的解法比二分的解法会更加简洁,也更符合人的思考思维。在实现动态规划算法过程中,我们的一个核心思路是得找状态转移方程,即如何描述从一个状态转移到另一个状态。

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值