給定 n,求由 1...n 構成的結構不同的二叉搜索樹(BST)數量。
例:n=3 → 5 棵不同結構的 BST。
以 i (1≤i≤n) 為根,左子樹由 [1, i-1] 構成,右子樹由 [i+1, n] 構成。
設 f(k) 為 k 個節點的不同 BST 數,則:
f(0) = 1 (空樹) f(1) = 1 f(2) = f(0)f(1) + f(1)f(0) = 2 f(3) = f(0)f(2) + f(1)f(1) + f(2)f(0) = 5 ... f(n) = Σ f(i-1) * f(n-i) (i=1..n)
這正是卡特蘭數:C_n = (2n)! / ((n+1)! n!)
class Solution {
public:
int numTrees(int n) {
vector dp(n + 1, 0);
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; ++i) {
for (int k = 1; k <= i; ++k) {
dp[i] += dp[k - 1] * dp[i - k];
}
}
return dp[n];
}
};
class Solution {
public:
int numTrees(int n) {
long long catalan = 1;
for (int i = 0; i < n; ++i) {
catalan = catalan * 2 * (2 * i + 1) / (i + 2); // C_{i+1} = C_i * 2(2i+1)/(i+2)
}
return (int)catalan;
}
};
| 方法 | 時間 | 空間 | 備註 |
|---|---|---|---|
| DP 遞推 | O(n²) | O(n) | 通用、易理解 |
| 卡特蘭公式 | O(n) | O(1) | 需防溢出、面試加分 |

若需生成所有結構,需遞歸構建左右子樹列表並組合,時間空間均為卡特蘭數級別。