1. 程式人生 > >演算法導論程式3--最大子陣列問題(Python)

演算法導論程式3--最大子陣列問題(Python)

尋找最大子陣列問題:

給定陣列A:尋找A中的和最大的非連續子陣列。我們稱這樣的連續子陣列為最大子陣列(maximum subarray)

使用分治策略的求解方法:

假定我們要尋找子陣列A[low...high]的最大子陣列。使用分治技術意味著我們要將子陣列劃分為兩個規模儘量相等的子陣列。也就是,找到子陣列的中央位置,比如mid,然後考慮求解兩個子陣列A[low...mid]和A[mid+1...high]。A[low...high]的任何連續子陣列A[i ...j]所處的位置必然是一下三種情況之一:

1.完全位於子陣列A[low...mid]中,因此low<=i<=j<=mid

2.完全位於子陣列A[mid+1...high]中,因此mid<i<=j<=high

3.跨越了中點,因此low<=i<=mid<j<=high

我們可以遞迴地求解A[low...mid]和A[mid+1...high]的最大子陣列。剩下的全部工作就是尋找跨越中點的最大子陣列,然後在三種情況中選取最大者。

def find_max_crossing_subarray(A,low,mid,high):
    left_sum = float("-inf")
    sum = 0
    max_left = 0
    max_right = 0
    for i in range(mid,low-1,-1):
        sum = sum + A[i]
        if sum > left_sum:
            left_sum = sum
            max_left = i
    right_sum = float("-inf")
    sum = 0
    for j in range(mid+1,high+1):
        sum = sum + A[j]
        if sum > right_sum:
            right_sum = sum
            max_right = j
    return [max_left,max_right,left_sum+right_sum]


import math
def find_maximum_subarray(A,low,high):
    if high == low:
        return (low,high,A[low])
    else:
        mid = math.floor((low+high)/2)
        [left_low,left_high,left_sum] = find_maximum_subarray(A,low,mid)
        [right_low,right_high,right_sum] = find_maximum_subarray(A,mid+1,high)
        [cross_low,cross_high,cross_sum] = find_max_crossing_subarray(A,low,mid,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]
            
演算法執行時間複雜度分析: