本文原題: LeetCode.
給定 n, 求解獨特二叉搜尋樹 (binary search trees) 的個數.
什麼是二叉搜尋樹?
二叉查找樹(Binary Search Tree),或者是一棵空樹,或者是具有下列性質的二叉樹: 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; 它的左、右子樹也分別爲二叉排序樹。
舉個栗子,
給定 n = 3, 共有 5 個.
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
本題的解題思路如下:
設n對應的BST個數爲h(n), n-1對應的個數爲h(n-1)...依此類推.
那麼,
- 把1放在根節點, 2...n放在右側, 總種類是h(1) * h(n-1)
- 把2放在根節點, 1放在左側, 3...n放在右側, 總種類是h(2) * h(n-2)
- ....
- 把n放在根節點, 1...n-1放在左側, 總種類是h(n-1) * h(1)
所以h(n) = h(1) * h(n-1) + h(2) * h(n-2) +...+ h(n-2) * h(2) + h(n-1) * h(1)
上述h(n)表達式即爲卡特蘭數.(幽蘭止水的CSDN博客)
下面是實現的C++代碼:
class Solution {
public:
int numTrees(int n) {
if (n < 0) return 0;
vector<int> h(n+1, 0);
h[0] = 1;
for(int i = 1; i <= n; i++)
for (int j = 0; j < i; j++)
h[i] += h[j] * h[i-j-1];
return h[n];
}
};
第一行做輸入檢測.
第二, 三行定義樹的種類向量h, 長度爲n+1, 定義h[0]值爲1, 因爲1節點的情況下只有1種可能.
之後是一個二層嵌套for循環, 大循環控制計算h的下標i, 小循環按照i的值依次計算h[1,2,3,...,n].
詳細講一下小循環, h[i]是當前計算的種類數, 它等於h[0]*h[i-1] + h[1]*h[i-2] + ... + h[i-1]*h[0] 和上面提到的卡特蘭數相符. (需要注意的是, 每層小循環都需要前i-1個h的值.)
返回的是h[n], 即h向量中的第n+1個數, 但對應於n個節點的情況.
[本代碼存疑]