卡特蘭數(Catalan Number)是組合數學中一個極其重要的數列,由比利時數學家歐仁·查理·卡特蘭在研究凸多邊形三角剖分問題時發現。該數列在計算機科學、圖論、代數幾何等領域廣泛出現,Richard Stanley曾收集超過200種等價的組合解釋。
遞推公式:
C₀ = 1 Cₙ = Σᵢ₌₀ⁿ⁻¹ Cᵢ × Cₙ₋₁₋ᵢ (n ≥ 1)
通項公式:
Cₙ = (1/(n+1)) × C(2n, n) = (2n)! / ((n+1)! n!)
前16項:
| n | Cₙ | n | Cₙ |
|---|---|---|---|
| 0 | 1 | 8 | 1,430 |
| 1 | 1 | 9 | 4,862 |
| 2 | 2 | 10 | 16,796 |
| 3 | 5 | 11 | 58,786 |
| 4 | 14 | 12 | 208,012 |
| 5 | 42 | 13 | 742,900 |
| 6 | 132 | 14 | 2,674,440 |
| 7 | 429 | 15 | 9,694,845 |
給定編號 n,構造第 n 棵二叉樹(按特定順序編號),輸出其結構表示。
// 預計算卡特蘭數 C[0..19] (C[19] < 2^31)
long long C[20];
void initCatalan() {
C[0] = 1;
for (int i = 1; i < 20; i++) {
C[i] = 0;
for (int j = 0; j < i; j++)
C[i] += C[j] * C[i-1-j];
}
}
// 遞歸構造二叉樹
void buildTree(int n) { // n: 當前子樹的編號
if (n == 0) return; // 空樹
// 1. 找節點數
int nodes = 1;
while (n > C[nodes]) n -= C[nodes++];
// 當前子樹共 nodes 個節點(含根)
// 2. 找左子樹節點數
int leftNodes = 0;
while (n > C[leftNodes] * C[nodes-1-leftNodes]) {
n -= C[leftNodes] * C[nodes-1-leftNodes];
leftNodes++;
}
int rightNodes = nodes - 1 - leftNodes;
// 3. 找左右子樹編號
int leftIdx = (n - 1) / C[rightNodes] + 1;
int rightIdx = (n - 1) % C[rightNodes] + 1;
// 輸出當前根,遞歸處理左右子樹
printf("X"); // 或根據題目要求輸出具體表示
if (leftNodes > 0) buildTree(leftIdx);
if (rightNodes > 0) buildTree(rightIdx);
}
C[0] = 1;
for (int i = 1; i <= N; i++) {
C[i] = 0;
for (int j = 0; j < i; j++)
C[i] += C[j] * C[i-1-j];
}
C[0] = 1;
for (int i = 1; i <= N; i++)
C[i] = C[i-1] * 2 * (2*i - 1) / (i + 1); // 整除無餘數
n > 19 時超過 64 位整數範圍,需使用高精度庫(Java BigInteger、Python 原生大整數、C++ 自定義大數類或 GMP)。
卡特蘭數是連接組合數學與計算機科學的橋樑。掌握其遞推定義、通項公式、經典模型、動態規劃計算,能靈活解決二叉樹計數、括號匹配、棧排列、路徑計數等大類問題。在算法競賽中,識別「卡特蘭數模型」往往是破題關鍵。