原题目:https://leetcode-cn.com/problems/unique-binary-search-trees/
思路1:
直觉就是递归的实现,每一次以i为根节点,i-1个数字为左子树,n-i个数字为右子树,则以i为根的二叉树数目是两个的乘积。
但是超时了,思路二进行优化。
代码:
class Solution {
public:
int numTrees(int n) {
if(n==0 || n==1) return 1;
int ans = 0;
for(int i=1;i<=n;i++){
ans += numTrees(i-1)*numTrees(n-i);
}
return ans;
}
};
思路2:
我们可以想到上面的方法其实计算了很多已经重复计算过的数。我们采用动态规划的思想, 使用数组来保存已经计算过的结果。
采用G(n)保存节点数目为n的BST的数目,令F(i,n)表示以i为根节点,节点数目为n的BST的数目。
则:G(n)=sum F(i,n)。
F(i,n) = G(i-1)*G(n-i)
边界条件:G[0] = 1,G[1]=1;
代码:
class Solution {
public:
int numTrees(int n) {
vector<int> G(n+1);
G[0]=1;G[1]=1;
for(int i=2;i<=n;i++){
for(int j=1;j<=i;j++){
G[i] += G[j-1]*G[i-j];
}
}
return G[n];
}
};
思路3:
其实上面的数组G就是卡特兰数。
代码;
class Solution {
public:
int numTrees(int n) {
long c=1;
for(int i=0;i<n;i++){
c = c*2*(2*i+1)/(i+2);
}
return int(c);
}
};