Unique Binary Search Trees

一. 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

Difficulty:Medium

TIME:21MIN

解法(動態規劃)

其實這道題採用的就是典型的分治法,以根節點爲中心,將二叉查找樹分爲左右兩個子二叉查找樹,然後分別計算子二叉查找樹數的可能個數,再相乘(注意這裏是相乘)。

比如對於3個結點的二叉查找樹,可以分爲<0,2>,<1,1>,<2,0>三種結構,因此總的個數爲2+1+2=5。

知道了做法只會就很容易聯想到動態規劃,這樣就可以避免重複計算相同的值,解法如下:

int numTrees(int n) {
    if(n == 0)
        return 0;
    vector<int> dp(n + 1, 0);
    dp[1] = 1;
    dp[0] = 1;
    for(int i = 2; i <= n; i++) {
        for(int j = 1; j <= i; j++) {
            dp[i] += dp[j - 1] * dp[i - j]; //左子樹個數乘以右子樹個數
        }
    }
    return dp[n];
}

代碼的時間複雜度爲O(n2)

二. Unique Binary Search Trees II

Given an integer n, generate all structurally unique BST’s (binary search trees) that store values 1…n.

For example,

Given n = 3, your program should return all 5 unique BST’s shown below.

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

Difficulty:Medium

TIME:TIMEOUT

解法

這道題和上面那道題幾乎是一樣的,不過這道題是是求具體的二叉查找樹,而不是求個數,因此就不能使用動態規劃了。

其實思路是有點類似的,也是採用分治法,先求左右兩邊子樹的所有二叉查找樹,然後再加上根節點。

vector<TreeNode*> dfs(int left, int right) {
    vector<TreeNode*> v;
    /*空節點*/
    if(left > right) {
        v.push_back(NULL);
        return v;
    }
    /*單節點*/
    if(left == right) {
        v.push_back(new TreeNode(left));
        return v;
    }
    for(int i = left; i <= right; i++) {
        vector<TreeNode*> l = dfs(left, i - 1); //生成所有左子樹
        vector<TreeNode*> r = dfs(i + 1, right); //生成所有右子樹
        /*用根節點連接所有左子樹和右子樹*/
        for(int j = 0; j < l.size(); j++) { 
            for(int k = 0; k < r.size(); k++) {
                TreeNode *root = new TreeNode(i);
                root->left = l[j];
                root->right = r[k];
                v.push_back(root);
            }
        }
    }
    return v;
}
vector<TreeNode*> generateTrees(int n) {
    vector<TreeNode*> v;
    if(n == 0)
        return v;
    return dfs(1, n);
}

不太清楚代碼的時間複雜度。

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