解题思路:
蛮力法:
求连续和最大,可以设置一个值 result 保存和的最大值。先将这个值 result 初始化最小值,每求一个和,与这个值比较,若和大,把和赋给这个值,
若和不大于0,在后面重新求和,比较最大值保存
最后返回这个值就是最大
result = -float('inf') #初始化最小值
count = 0
for i in range(len(nums)):
count += nums[i] #从第一个开始加和
if count > result:
result = count #保存最大值
if count <= 0: #若有不大于0的从新开始加和
count = 0
return result
分治法:
将数组进行分解,分而治之,递归求解。
考虑分成左右两部分,左右各有一个最大值,又从中间向左和向右这一部分数也可能是连续最大的,即最终需要比较一下左,中,右三部分最大值即可。
中间部分求最大值:即从中间向左进行加和保留该过程中最大值,向右进行加和保留最大值,两部分相加即为中间部分最大值。
def MergeMidMax(ls, low, mid, high):
"""
从数组中间开始,向左找最大连续和,向右找最大连续和,二者相加返回
:param ls:
:param low: 左边界
:param mid: 中间下标
:param high: 右边界
:return:
"""
Max_Left = float("-inf") # 求左边最大连续和
Max_Right = float("-inf") # 求右边最大连续和
Sum = 0
for i in range(mid, low-1, -1): # 从中间向左加和
Sum += ls[i]
Max_Left = max(Max_Left, Sum)
Sum = 0
for j in range(mid+1, high+1): # 从中间向右加和
Sum += ls[j]
Max_Right = max(Max_Right, Sum)
Sum_LR = Max_Right + Max_Left
return Sum_LR
def MaxSubSum(ls, low, high):
if low == high:
return ls[low]
else:
mid = (low + high) // 2
LMax = MaxSubSum(ls, low, mid) # 递归求左部分
RMax = MaxSubSum(ls, mid + 1, high) # 递归求右部分
MidMax = MergeMidMax(ls, low, mid, high)
FinalMax = max(LMax, RMax, MidMax)
return FinalMax
if __name__ == "__main__":
ls = [-3, 12, -5, 13, -5, 10, -2, 1]
m = MaxSubSum(ls, 0, len(ls) - 1)
print(m) # 25