//算法导论笔记
递归求最大(和)子数组
核心思想:
-假设最大子数组存在,则仅有三种情况:
a.在中点左侧[beg : mid];
b.在中点右侧[mid+1: end];
c.跨越(包含)了中点(即head<=mid && tail >=mid+1);
-分成三类以后分别对这三种类别的Subarray求最大子数组,即递归;
-其中a类b类都不跨中点,则直接递归;
-c类跨中点,考虑max(x + y) = max(x) + max(y),各自找到中点左右两侧的最大子数组
-Python
0.针对c类子数组找最大子数组
def Find_Max_Crossing_SubArray(A, beg, mid, end):
#acquire that mid < end
Lsum = A[mid]
Rsum = A[mid+1]
Lidx = mid
Ridx = mid+1 #offer a default case
sum = 0
for i in range(mid, beg-1, -1):
sum += A[i]
if sum > Lsum:
Lsum = sum #Find Left_Max_Sum and index
Lidx = i
sum = 0
for j in range(mid+1, end+1):
sum += A[j]
if sum > Rsum:
Rsum = sum #Find_Right_Max_Sum and index
Ridx = j
return (Lidx, Ridx, Lsum + Rsum)
就酱得到了候选坐标和候选最大和( •̀ ω •́ )y!
1.结合整体递归求最大子数组
def Find_Max_SubArray(A, beg, end):
if beg == end: #base case
return (beg, end, A[beg])
mid = (beg + end)//2 #recursive part!
(Lbeg, Lend, Lsum) = Find_Max_SubArray(A, beg, mid) #a-class
(Rbeg, Rend, Rsum) = Find_Max_SubArray(A, mid+1, end) #b-class
(Cbeg, Cend, Csum) = Find_Max_Crossing_SubArray(A, beg, mid, end) #mid-point-crossing-class
if Lsum >= Rsum and Lsum >= Csum:
return (Lbeg, Lend, Lsum)
if Rsum >= Lsum and Rsum >= Csum:
return (Rbeg, Rend, Rsum)
else:
return (Cbeg, Cend, Csum)
从三种类别的子数组分别得到了候选坐标和候选最大和,就可以比较了( •̀ ω •́ )y!
-运行时间nlgn