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

不太清楚代码的时间复杂度。

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