版权声明:本文为博主原创文章,欢迎评论 https://blog.csdn.net/wh_585/article/details/82155010
暴力递归方法
def maxChildArray(arr):
lenArr = len(arr)
maxLocation = [[-9999999999999, 0, 0]] #数据由3个子项构成,最大值,起点,长度
for i in range(lenArr): #取数据-第i轮 第i轮取i + 1个数据
for j in range(lenArr): #从哪个位置开始取数据
tmp = 0
if j + i <= lenArr - 1: #判断索引是否越界
for k in range(j, j + i + 1): #range(j, j + i + 1)从第j个开始取数据,额外可以取i个, j + i + 1取不到
tmp += arr[k] #求和未使用sum()函数,是因为不想对原数组进行切片操作,需占用额外空间
if tmp > maxLocation[0][0]:
maxLocation.clear()
maxLocation.append([tmp, j, i + 1])
elif tmp == maxLocation[0][0]:
maxLocation.append([tmp, j, i + 1])
return maxLocation
上述方法可以若数组中存在多组解,则会返回包含所有解的列表,这种方法的弊端在于空间复杂度过高O(n**3)
分治法 + 递归求解思路
"""
分治法:
left:左边最大值
right:右边最大值
post + pre: 最大后缀 + 最大前缀
最大值: max(left, right, post + pre)
"""
import math
def maxArraySub(arr, from_, to):
print('from: {}, to: {}'.format(from_, to))
if from_ == to:
return arr[to]
mid = math.floor((from_ + to)/2)
left = maxArraySub(arr, from_, mid)
right = maxArraySub(arr, mid + 1, to)
postLeft = now = arr[mid]
for i in range(mid - 1, from_ - 1, -1):
now += arr[i]
postLeft = max(now, postLeft)
preRight = now = arr[mid + 1]
for i in range(mid + 2, to + 1):
now += arr[i]
preRight = max(now, preRight)
print(left, right, postLeft, preRight)
return max(left, right, postLeft + preRight)
该方法将时间复杂度降至O(nlogn),已经算是很有进步,但是对于此题优化方式还未完事,请继续观看
动态规划
"""
DP求解最大子数组和问题
该问题可以理解为,某一项的最大前缀值为整个数组的子数组求和中最大的
存在:a[i] 使得 a[n] + ... + a[i] >= sum(sub(arr)p)(
即:从arr的子数组中任取一项的值均小于或等于以i为结尾的数组的最大前缀的值)
"""
def maxChildArrDP(arr):
dp = [arr[0]] #此处使用数组仍然具有可以优化的空间
for i in range(1, len(arr)):
if dp[i - 1] + arr[i] >= arr[i]:
dp.append(dp[i - 1] + arr[i])
else:
dp.append(arr[i])
return max(dp)
#通过使用pre记录前一项的最大前缀和,和当前变量作比较,滚动记录前一项最大前缀和,无需开辟n长空间
#优化空间
#opti stands for optimization 优化
def maxChildArrDPOpti(arr):
pre = arr[0] #记录前一个最大前缀
sum = arr[0] #记录最终结果
for i in range(1, len(arr)):
if pre + arr[i] >= arr[i]:
pre = arr[i] + pre
else:
pre = arr[i]
sum = pre if pre >= sum else sum
return sum
一般越是精简的代码,在代码中蕴含的东西越多,每一步的优化过程都是从之前的问题中发现新的问题,在此基础上进行改进,通过使用动态规划方法,将时间复杂度由O(nlogn)优化到O(n),空间复杂度O(1),至此最大子数组和最大的问题求解完成,整个优化过程如上所述,如果哪里有问题欢迎留言探讨。