题目:
给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
解法:
方法一:
用动态规划来解决这个问题。对于任意节点i(1<=i<=n),则有f(n) += f(i-1) * f(n - i)。
把上面的例子的顺序更改下,就可以看到规律了。
比如,以1为根的树有几个,完全取决于有两个元素的子树有几种。同理,以2为根的子树取决于一个元素的子树有几个。以3为根的情况,则与1相同。
定义num[i]为以[0,i]能产生的Unique Binary Tree的数目,则有:
如果数组为空,毫无疑问,只有一种BST,即空树,num[0] = 1;
如果数组仅有一个元素{1},只有一种BST,单个节点,num[1] = 1;
如果数组有两个元素{1, 2},那么有如下两种可能:
num[2] = num[0] * num[1] (1为根的情况)
+ num[1] * num[0] (2为根的情况)
再看一遍三个元素的情况,可以发现BST的取值方式为:
num[3] = num[0] * num[2](1为根的情况)
+ num[1] * num[1] (2为根的情况)
+ num[2] * num[0] (3为根的情况)
具体代码如下所示。
1 class Solution { 2 public: 3 int numTrees(int n) 4 { 5 vector<int> num(n+1, 0); 6 num[0] = 1; 7 if (n > 0) 8 { 9 num[1] = 1; 10 } 11 12 for (int i = 2; i < n + 1; i++) 13 { 14 for (int j = 0; j < i; j++) 15 { 16 num[i] += num[j]*num[i-j-1]; 17 } 18 } 19 20 return num[n]; 21 } 22 };
方法二:
具体代码如下所示:
1 class Solution { 2 public: 3 int numTrees(int n) 4 { 5 long c = 1; 6 for (int i = 2; i <= n; i++) 7 { 8 c = 2 * (2 * i - 1) * c / (i+1); 9 } 10 11 return c; 12 } 13 };