1. 程式人生 > >[LeetCode] Unique Binary Search Trees 獨一無二的二叉搜尋樹

[LeetCode] Unique Binary Search Trees 獨一無二的二叉搜尋樹

Given n, how many structurally unique BST's (binary search trees) that store values 1...n?

For example,
Given n = 3, there are a total of 5 unique BST's.

   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_0 = 1 \quad \mbox{and} \quad C_{n+1}=\sum_{i=0}^{n}C_i\,C_{n-i}\quad\mbox{for }n\ge 0.

我們根據以上的分析,可以寫出程式碼如下:

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];
    }
};