Medium!
題目描述:
給定一個整數 n,求以 1 ... n 為節點組成的二叉搜索樹有多少種?
示例:
輸入: 3 輸出: 5 解釋: 給定 n = 3, 一共有 5 種不同結構的二叉搜索樹: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
解題思路:
這道題實際上是 Catalan Number卡塔蘭數的一個例子,如果對卡塔蘭數不熟悉的童鞋可能真不太好做。先來看當 n = 1的情況,只能形成唯一的一棵二叉搜索樹,n分別為1,2,3的情況如下所示:
1 n = 1 2 1 n = 2 / \ 1 2 1 3 3 2 1 n = 3 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
就跟斐波那契數列一樣,我們把n = 0 時賦為1,因為空樹也算一種二叉搜索樹,那么n = 1時的情況可以看做是其左子樹個數乘以右子樹的個數,左右字數都是空樹,所以1乘1還是1。那么n = 2時,由於1和2都可以為跟,分別算出來,再把它們加起來即可。n = 2的情況可由下面式子算出:
dp[2] = dp[0] * dp[1] (1為根的情況)
+ dp[1] * dp[0] (2為根的情況)
同理可寫出 n = 3 的計算方法:
dp[3] = dp[0] * dp[2] (1為根的情況)
+ dp[1] * dp[1] (2為根的情況)
+ dp[2] * dp[0] (3為根的情況)
由此可以得出卡塔蘭數列的遞推式為:
我們根據以上的分析,可以寫出代碼如下:
C++解法一:
我們根據以上的分析,可以寫出代碼如下:
class Solution { public: int numTrees(int n) { vector<int> dp(n + 1, 0); dp[0] = 1; dp[1] = 1; for (int i = 2; i <= n; ++i) { for (int j = 0; j < i; ++j) { dp[i] += dp[j] * dp[i - j - 1]; } } return dp[n]; } };