最大连续子数组问题(python3实现)

关于最大连续子数组问题,即求一个给定数组中和最大的一个连续子数组的和。
我们这里用动态规划的思想来解决这个问题。
我们以s[i]记为以a[i]为结尾的数组和中的最大子数组
则此时我们可以得到s[i+1] = max(s[i]+a[i+1] , a[i+1])
接下来,我们举例进行说明。假设有个数组如下
a 2 -3 -4 9 10
sum[i] (前i项和) 2 -1 -5 4 14
根据上述递推关系式
s[0] = a[0] = 2 = s[0]
s[1] = max(-1, -3) =  -1 = s[1]
s[2] = max(-5,-4) = -4 = a[2]
此时起点应该变更为a[2] ,
s[3] = max(4,9) = 9 = a[3]
此时起点应该为以a[3] 然后依次进行。


此时我们对上述的动态规划式子还可以进行一个优化。对于s[i+1] = max(s[i]+a[i+1] , a[i+1])
我们知道,当s[i]<0时,s[i]+a[i] < a[i]恒成立,而s[i]>0时,s[i]+a[i] > a[i]恒成立
于是我们又有了新的递推式,用于简化刚才的计算。我们依然用上述例子说明
a 2 -3 -4 9 10
sum[i] (前i项和) 2 -1 -5 4 14
我们根据sum[i]的正负,即可判断起点从a[3] = 9开始。
所以,关于该问题产生的代码如下
import random


def max_list(num_list):
    result = num_list[0]
    sum = num_list[0]
    start = 0                   #记录最大连续子数组起点站
    end = 0                     #记录最大连续子数组终点站
    for i in range(1, len(num_list)):
        if sum > 0:             #前n 项和sum>0       sum[i+1] = sum[i]+num_list[i]
            sum += num_list[i]
        else:                   #前n 项和sum <= 0       sum[i+1] = num_list[i]
            start = i
            sum = num_list[i]
        if sum > result:
            end = i
            result = sum
    return result, end, start

if __name__ == '__main__':
    num_list = list(random.sample(range(-11,20), 15))
    print(num_list)
    print(max_list(num_list))

你可能感兴趣的:(算法)