LCS 和 LIS
最長共同子序列 (Longest Common Subsequence)
最長共同子序列
子序列是指一個序列去除任意個(包含 0)元素後所形成的新序列。 給定兩序列 ,求最長的序列 , 同時為 的子序列。
- 狀態: 表示使用 和 的 LCS 長度。
- 初始狀態: when
- 轉移:
求出 LCS 的時間、空間複雜度都是 ,使用滾動陣列技巧,可將空間複雜度降至 。
最長遞增子序列 (Longest Increasing Subsequence)
最長遞增子序列
給你一個序列 ,求最長的序列 , 是一個(非)嚴格遞增序列,且為 的子序列。
- 狀態: :第 到 個數字所形成最長遞增子序列的長度
- 轉移:
- 初始化:
求出 LIS 的時間複雜度 ,空間複雜度
LCS 和 LIS 題目轉換
- LIS 轉成 LCS
- 為原序列,
- 對 做 LCS
- LCS 轉成 LIS
- 為原本的兩序列
- 最 序列作編號轉換,將轉換規則套用在
- 對 做 LIS
- 重複的數字在編號轉換時後要變成不同的數字,越早出現的數字要越小
- 如果有數字在 裡面而不在 裡面,直接忽略這個數字不做轉換即可
LIS 的時間複雜度從 降至
LIS 還有另一種狀態轉移式:
- 狀態: 表示使用前 個數字湊出長度 的 LIS, 末端數字最小為何。
- 轉移:
- 初始狀態: when
這樣的狀態轉移式時間和空間複雜度依舊是 ,不過,有幾點值得觀察:
令 , where ,忽略 , 為一個嚴格遞增序列,當 每次 , 每次都有一個數字改變,改變的數字皆為 ,被改的數字為 。
根據上述性質,可用二分搜更新 ,藉此找到 LIS 的長度。每次二分搜的時間複雜度為 ,整體時間複雜度為 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|