最長不下降序列
最長不下降序列(Longest Increasing Subsequence,LIS)是一個在數列中尋找最長的元素序列,且這些元素依序遞增的問題。例如,給定數列 [10, 22, 9, 33, 21, 50, 41]
,其最長不下降序列為 [9, 21, 33, 41, 50]
,長度為5。
最長不下降序列問題在許多領域都有應用,例如在生物學中用於比對基因序列,在計算機科學中用於排序和線性複雜度的最短路徑問題,以及在經濟學中用於價格分析等。
解決最長不下降序列問題可以使用動態規劃(Dynamic Programming)的方法。基本思路是將問題分解為較小的子問題,並記錄已經解決的子問題的答案,以避免重複計算。
以下是使用動態規劃解決最長不下降序列問題的算法:
- 初始化一個長度與數列相同的數組
lis
,用來存儲最長不下降序列的長度。 - 對於數列中的每一個元素
nums[i]
,檢查nums[i]
是否可以作為最長不下降序列的終點。 - 如果
nums[i]
比nums[0..i-1]
中的所有元素都大,那麼nums[i]
就可以作為最長不下降序列的終點。 - 更新
lis[i]
的值為lis[0..i-1]
中的最大值加上 1。 - 最後,找到
lis
中的最大值,並從數列中找出對應的最長不下降序列。
以下是一個簡單的Python實現:
def lis(nums):
n = len(nums)
lis = [1] * n # 初始化最長不下降序列的長度為1
for i in range(n):
for j in range(i):
if nums[i] <= nums[j]:
lis[i] = max(lis[i], lis[j] + 1)
return lis, max(lis)
# 示例
nums = [10, 22, 9, 33, 21, 50, 41]
lis_length, max_lis_length = lis(nums)
print(f"The length of the longest increasing subsequence is {max_lis_length}")
print(f"The subsequence is {[nums[i] for i in range(len(nums)) if lis_length[i] == max_lis_length]}")
這個算法的時間複雜度為 O(n^2)
,空間複雜度為 O(n)
。對於較大的數列,可以使用二維數組來優化時間複雜度到 O(n log n)
,或者使用分治法來達到線性時間複雜度 O(n)
。