[LeetCode] 96. 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

此题是卡塔兰数的一个应用。注意是BST而不是普通的Binary Tree,所以要满足左比根小,右比根大。

                    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
 
定义f(n)为unique BST的数量,以n = 3为例:
构造的BST的根节点可以取{1, 2, 3}中的任一数字。
如以1为节点,则left subtree只能有0个节点,而right subtree有2, 3两个节点。所以left/right subtree一共的combination数量为:f(0) * f(2) = 2
以2为节点,则left subtree只能为1,right subtree只能为3:f(1) * f(1) = 1
以3为节点,则left subtree有1, 2两个节点,right subtree有0个节点:f(2)*f(0) = 2
总结规律:
f(0) = 1
f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... + f(n-2)*f(1) + f(n-1)*f(0)

Java: DP

class Solution {  
    public int numTrees(int n) {
      int[] count = new int[n + 1];

      count[0] = 1;
      count[1] = 1;

      for (int i = 2; i <= n; i++) {
        for (int j = 0; j <= i - 1; j++) {
          count[i] = count[i] + count[j] * count[i - j - 1];
        }
      }

      return count[n];
    }  
}    

Python: Math

class Solution(object):
    def numTrees(self, n):
        if n == 0:
            return 1

        def combination(n, k):
            count = 1
            # C(n, k) = (n) / 1 * (n - 1) / 2 ... * (n - k + 1) / k
            for i in xrange(1, k + 1):
                count = count * (n - i + 1) / i;
            return count

        return combination(2 * n, n) - combination(2 * n, n - 1)

Python: DP

class Solution2:
    def numTrees(self, n):
        counts = [1, 1]
        for i in xrange(2, n + 1):
            count = 0
            for j in xrange(i):
                count += counts[j] * counts[i - j - 1]
            counts.append(count)
        return counts[-1]

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

 

类似题目:

[LeetCode] 96. Unique Binary Search Trees II 唯一二叉搜索树 II

All LeetCode Questions List 题目汇总

 

posted @ 2018-03-10 15:22  轻风舞动  阅读(439)  评论(0编辑  收藏  举报