最大子數列問題
最大子數列問題(Maximum Subarray Problem)是一個著名的動態規劃問題,其目標是在一個給定的數列中找到一個連續子數列,使得這個子數列的和最大。這個問題有許多實際應用,例如在投資組合管理中,可以找到一段時間內股票投資的最大收益。
問題描述:
給定一個數列 A
,找到一個連續子數列 A[i..j]
,使得 sum(A[i..j])
最大。
動態規劃解法:
我們可以使用動態規劃來解決這個問題。我們定義一個狀態 dp[i]
表示以 A[i]
為最後一個元素的最大子數列的總和。狀態轉移方程為:
dp[i] = max(dp[i-1] + A[i], A[i])
初始狀態 dp[0] = A[0]
。
時間複雜度:O(n)
,其中 n
是數列 A
的長度。
空間複雜度:O(n)
,因為我們需要 dp
陣列的大小為 n
。
下面是一個Python的實現:
def maxSubArray(A):
n = len(A)
dp = [0] * n
dp[0] = A[0]
for i in range(1, n):
dp[i] = max(dp[i-1] + A[i], A[i])
return dp[-1]
# 示例
A = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]
print(maxSubArray(A)) # 應該輸出44
Kadane's Algorithm: 最大子數列問題有一個更高效的解決方案,稱為Kadane's Algorithm,它可以在線性時間內解決這個問題。這個算法的思想是,在尋找最大子數列的過程中,我們同時更新全局最大值和當前局部最大值。如果當前元素加上局部最大值大於全局最大值,則更新全局最大值。
時間複雜度:O(n)
。
空間複雜度:O(1)
,因為我們只需要兩個額外的變量來存儲局部最大值和全局最大值。
下面是Kadane's Algorithm的Python實現:
def maxSubArrayKadane(A):
n = len(A)
max_ending_here = A[0]
max_so_far = A[0]
for i in range(1, n):
max_ending_here = max(max_ending_here + A[i], A[i])
max_so_far = max(max_so_far, max_ending_here)
return max_so_far
# 示例
A = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]
print(maxSubArrayKadane(A)) # 應該輸出44