Python实现最大连续子数组和:暴力、分治与动态规划详解
本文深入解析Python中求最大连续子数组和的三种核心算法。首先介绍时间复杂度为O(n^2)的暴力求解法,随后讲解通过递归将问题分解以降低复杂度的分治策略,最后重点阐述时间复杂度为O(n)的动态规划方法。文章提供完整代码示例,帮助开发者根据实际需求选择最优方案。
抛出问题:
给定一个整数数组,例如 l = [0, 1, 2, 3, -4, 5, -6],我们需要计算该数组中最大连续子数组的和。例如,子数组 [0, 1, 2, 3, -4, 5] 的和为 7,这可能就是最大和。
问题分析:
这个问题相对直观,我们可以直接使用暴力法来解决,具体代码实现如下。
# -*- coding:utf-8 -*-
# 日期:2018/6/9 7:46
# Author:小鼠标
# 最大连续子数组的和
l = [0, 1, 2, 3, -4, 5, -6]
# 暴力求解
def violence(l = []):
maxVal = 0
x,y=0,0
for i in range(0,len(l)+1):
for j in range(0,len(l)+1):
res = sum(l[i:j])
if res > maxVal:
maxVal = res
x = i
y = j
return maxVal,x,y
maxVal, x, y = violence(l)
print(maxVal,(x,y))
分治法:
鉴于暴力法的时间复杂度较高,我们在其基础上进行了优化,引入了分治法来提升性能。
分治法的核心思想是将原列表从中间一分为二,此时最大连续子数组只可能出现在以下三种情况之一:
1、最大子数组完全位于左半部分。
2、最大子数组完全位于右半部分。
3、最大子数组跨越中间分界线,即由左半部分的后缀和右半部分的前缀组成。
因此,我们需要分情况讨论并计算这三种情况的最大值。这种方法在一定程度上降低了时间复杂度,从之前的 n^2 降到了 (n/2)^2 + 2n。
# -*- coding:utf-8 -*-
# 日期:2018/6/9 7:46
# Author:小鼠标
# 最大连续子数组的和
l = [0, 1, 2, 3, -4, 5, -6]
#暴力求解
def violence(l = []):
maxVal = 0
x,y=0,0
for i in range(0,len(l)+1):
for j in range(0,len(l)+1):
res = sum(l[i:j])
if res > maxVal:
maxVal = res
x = i
y = j
return maxVal,x,y
#分治法 想左扫 向右扫,求出两边的最大值
def left_or_right(l):
maxVal = 0
term = 0
for i in l:
term += i
if maxVal < term:
maxVal = term
return maxVal
def Separate():
middle = int(len(l)/2)
l1 = l[0:middle]
l2 = l[middle:len(l)]
#左半部分
maxVal1,x1,y1 = violence(l1)
#右半部分
maxVal2,x2,y2 = violence(l2)
#跨立在中间
max_right = left_or_right(l2)
max_left = left_or_right(l1[::-1])
maxVal3 = max_right + max_left
return max(maxVal1,maxVal2,maxVal3)
val = Separate()
print(val)
动态规划:
尽管分治法有所改进,但其时间复杂度仍然较高,可能无法满足某些生产环境的需求。如果我们的目标仅仅是求最大子序列的和的值,而不需要返回具体的子序列,那么可以引入另一种方法——动态规划。
这种方法的时间复杂度是线性的,极大地降低了计算开销。
# -*- coding:utf-8 -*- # 日期:2018/6/9 8:38 # Author:小鼠标 def function(lists): max_sum = lists[0] pre_sum = 0 for i in lists: # 因为最大子列表一定是从一个非0的数开始的(假定列表中有正数有负数) # 所以就可以暂时筛选调小于0的数,即便列表全是负数,那么最大的子列表肯定是负数最大的一个 if pre_sum < 0: pre_sum = i else: pre_sum += i if pre_sum > max_sum: max_sum = pre_sum return max_sum lists = [0, 1, 2, 3, -4, 5, -6] print(function(lists))
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













