最长递增子序列
最長遞增子序列(Longest Increasing Subsequence,LIS)是一個在數組中找到的子序列,該子序列的元素是遞增的,並且在該數組中沒有更長的遞增子序列。
例如,對於數組 [2, 3, 1, 6, 5, 7, 4]
,其最長遞增子序列為 [1, 3, 5, 7]
,因為它是可能的最大長度,且元素是遞增的。
最長遞增子序列問題是一個經典的動態規劃問題,可以通過動態規劃算法來解決。動態規劃算法的基本思想是定義一個狀態,該狀態表示解決子問題所需的信息,然後使用這些狀態來構建一個決策過程,從而找到最優解。
對於最長遞增子序列問題,我們可以定義狀態 dp[i]
為以 A[i]
結尾的最長遞增子序列的長度。我們可以使用以下動態規劃方程來計算這個狀態:
dp[i] = 1 + max(dp[j] where A[j] < A[i] and j < i)
這個方程的意思是,以 A[i]
結尾的最長遞增子序列的長度,等於以 A[i-1]
結尾的最長遞增子序列的長度,加上 1,如果存在的話。如果不存在這樣的子序列,則 dp[i]
為 1。
我們可以使用一個循環來計算 dp[i]
的值,然後找到最大的 dp[i]
來找到最長遞增子序列的長度。我們可以使用一個堆疊來找到實際的子序列。
以下是一個簡單的Python實現:
def lis(A):
n = len(A)
dp = [1] * n # 初始化狀態
for i in range(1, n):
for j in range(i):
if A[i] > A[j]:
dp[i] = max(dp[i], dp[j] + 1)
max_len = max(dp)
lis = []
for i in range(n):
if dp[i] == max_len:
lis.append(A[i])
return lis
# 示例
A = [2, 3, 1, 6, 5, 7, 4]
print(lis(A)) # 輸出: [1, 3, 5, 7]
這個算法的時間複雜度為 O(n^2),空間複雜度為 O(n)。對於較大的數組,這個時間複雜度可能太高。我們可以使用二分查找等技巧來最佳化這個算法,使其時間複雜度為 O(n log n)。