分支策略
方法:
1. 分解;
2. 解决;
3. 合并;
核心:递归式;
最大子数组
概念:一个数组中连续索引之间的和最大的子数组;
问题解决办法:
1. 将数组分为左,右,左右交叉数组;
2. 单独递归左右交叉数组;
3. 统一递归左右数组;
代码部分
- 解决左右交叉数组的递归问题
# 1. 解决左右交叉数组的递归问题
def find_cross_max_subarray(arr, low, middle, high):
max_right, max_left = 0, 0 # 设置获取右边最大值和左边最大值
left_sum = -99 # 初始化左边数组最大值
sums = 0 # 初始化保存左边最大值
# 遍历从中间分割部分到头索引的元素
for i in range(middle, low - 1, -1):
sums += arr[i]
if sums > left_sum:
left_sum = sums
max_left = i
right_sum = -99 # 设置最右边数组最大值
sums = 0 # 初始化保存右边最大值
# 遍历从中间+1的索引位置到最后一个数组的索引
for j in range(middle + 1, high + 1):
sums += arr[j]
if sums > right_sum:
right_sum = sums
max_right = j
# 返回左边最大值,右边最大值,中间和值
return max_left, max_right, left_sum + right_sum
- 解决左边右边和同时解决返回值最大值和最大子数组索引位置
def find_maximum_subarray(arr, low, high):
if high == low: # 如果只有一个元素,则直接返回索引位置和该数组元素
return low, high, arr[low]
else:
# 获取数组的中间索引位置
middle = (low + high) // 2
# 递归解决最左边的数组获取最大子数组的索引和最大值
left_low, left_high, left_sum = find_maximum_subarray(arr, low, middle)
# 递归解决最右边的数组获取最大子数组的索引和最大值
right_low, right_high, right_sum = find_maximum_subarray(arr, middle + 1, high)
# 递归解决交叉部分数组获取最大子数组的索引和最大值
cross_low, cross_high, cross_sum = find_cross_max_subarray(arr, low, middle, high)
# 如果最左边的值大于中间值和最右值,则返回最左值和最左子数组的索引
if left_sum >= right_sum and left_sum >= cross_sum:
return left_low, left_high, left_sum
# 如果最右边的值大于中间值和最左值,则返回最右值和最右子数组的索引
elif right_sum >= left_sum and right_sum >= cross_sum:
return right_low, right_high, right_sum
# 如果最中间的值大于最左值和最右值,则返回中间最大值和中间最大子数组的索引
else:
return cross_low, cross_high, cross_sum
- 主函数部分
if __name__ == '__main__':
arrays = [-1, 2, 4, 6, -2, 3, 1, 0]
print("初始序列", arrays)
lows, highs, sums = find_maximum_subarray(arrays, 0, len(arrays) - 1)
print("最大子数组左索引: {0}\n最大子数组右索引: {1}\n最大子数组的和值: {2}".format(lows, highs, sums))
- 控制台输出部分
初始序列 [-1, 2, 4, 6, -2, 3, 1, 0]
最大子数组左索引: 1
最大子数组右索引: 6
最大子数组的和值: 14
版权声明:本文为m0_51894865原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。