[LeetCode系列]卡特蘭數(Catalan Number) 在求解獨特二叉搜尋樹(Unique Binary Search Tree)中的應用分析

本文原題: 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個節點的情況.

[本代碼存疑]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章