最大子数组-分治法

最大子数组:寻找A的和最大的非空连续子数组

 1 #最大子数组
 2 
 3 #求跨越中点的最大子数组
 4 def find_max_crossing_subarray(A, low, mid, high):
 5     # 先求A[low,mid]的最大子数组,一定是【A[i],mid】
 6     left_sum = float("-inf")#目前为止找到的左边的最大和
 7     sum = 0#A【i..mid 】中所有值的和
 8     max_left = 0#左边的最大下标
 9     max_right = 0#右边的最大下标
10     for i in range(mid, low - 1, -1):
11         sum = sum + A[i]
12         if sum > left_sum:
13             left_sum = sum
14             max_left = i
15     #先求A[mid+1,high]的最大子数组,一定是【mid+1,A[j]】
16     right_sum = float("-inf")
17     sum = 0
18     for j in range(mid + 1, high + 1):
19         sum = sum + A[j]
20         if sum > right_sum:
21             right_sum = sum
22             max_right = j
23     #返回下标和值
24     return [max_left, max_right, left_sum + right_sum]
25 
26 import math
27 
28 #分治法求解最大子数组,返回子数组的左右下标和总值
29 def find_maximum_subarray(A, low, high):
30     if high == low:
31         return (low, high, A[low])
32     else:
33         mid = math.floor((low + high) / 2)
34         #递归求解在左边,在右边和跨中点的最大子数组
35         [left_low, left_high, left_sum] = find_maximum_subarray(A, low, mid)
36         [right_low, right_high, right_sum] = find_maximum_subarray(A, mid + 1, high)
37         [cross_low, cross_high, cross_sum] = find_max_crossing_subarray(A, low, mid, high)
38         if left_sum >= right_sum and left_sum >= cross_sum:
39             return [left_low, left_high, left_sum]
40         elif right_sum >= left_sum and right_sum >= cross_sum:
41             return [right_low, right_high, right_sum]
42         else:
43             return [cross_low, cross_high, cross_sum]
44 
45 A=[13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7]
46 
47 print(find_maximum_subarray(A, 0, len(A) - 1))
48 -----------------------------------------------------------------------
49 [7, 10, 43]
最大子数组

猜你喜欢

转载自www.cnblogs.com/yu-liang/p/9163742.html