95. 不同的二叉搜索树II
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:
正好按照顺序,左边比i小,右边比i大。
划分左右子树,递归构造。至于递归函数中为啥都用的是指针,是参考了,若不用指针,全部实例化的话会存在大量的对象拷贝,要调用拷贝构造函数,具体我尚且不太懂,感觉挺言之有理,不明觉厉。
代码
class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
//vector<TreeNode*>res;
if (n == 0)return{};
return *help(1,n);
}
vector<TreeNode*> *help(int start, int end)
{
vector<TreeNode*> *subTree = new vector<TreeNode*>();
if (start > end)subTree->push_back(NULL);
else
{
for (int i = start; i <= end; i++)
{
vector<TreeNode*> *leftSubTree = help(start, i - 1);
vector<TreeNode*> *rightSubTree = help(i+1,end);
for(int j=0;j<leftSubTree->size();j++)
for (int k = 0; k < rightSubTree->size(); k++)
{
TreeNode *node = new TreeNode(i);
node->left = (*leftSubTree)[j];
node->right = (*rightSubTree)[k];
subTree->push_back(node);
}
}
}
return subTree;
}
};
96. 不同的二叉搜索树
这道题实际上是 Catalan Number卡塔兰数的一个例子,如果对卡塔兰数不熟悉的童鞋可能真不太好做。
分析
就跟斐波那契数列一样,我们把n = 0 时赋为1,因为空树也算一种二叉搜索树,那么n = 1时的情况可以看做是其左子树个数乘以右子树的个数,左右字数都是空树,所以1乘1还是1。那么n = 2时,由于1和2都可以为根,分别算出来,再把它们加起来即可。n = 2的情况可由下面式子算出:
dp[2] = dp[0] * dp[1] (1为根的情况)
+ dp[1] * dp[0] (2为根的情况)
同理可写出 n = 3 的计算方法:
dp[3] = dp[0] * dp[2] (1为根的情况)
+ dp[1] * dp[1] (2为根的情况)
+ dp[2] * dp[0] (3为根的情况)
由此可以得出卡塔兰数列的递推式为:
得出卡塔兰数列的递推式为:
代码
class Solution {
public:
int numTrees(int n) {
if (n <= 0)return 0;
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-1; j++)
dp[i] += dp[j]*dp[i-1 - j];
}
return dp[n];
}
};
[1]http://fisherlei.blogspot.com/2013/03/leetcode-unique-binary-search-trees-ii.html
[2]https://www.cnblogs.com/ariel-dreamland/p/9159691.html