二叉搜索树满足的条件
- 当前根节点的值大于左子树节点的值
- 当前根节点的值小于右子树节点的值
- 左右子树同样是二叉搜索树
1: 找出所有二叉搜索树的个数
https://leetcode.com/problems/unique-binary-search-trees/description/
https://leetcode-cn.com/problems/unique-binary-search-trees/
给定数值n,计算有多少种不同的二叉搜索树能够存储1,2,...,n这n个数:
Solution:
example:
n=4,记最终结果为F(n), s(4,i)表示总共4个数,以i为根节点的搜索树的个数,
从而 F(4) = s(4,1) + s(4,2) + s(4,3) + s(4,4) ;
对于s(4,1):根节点1的左侧为null,即左子树的个数为1, 右侧为由“2 3 4”构成的所有子树,考虑到 2 3 4构成的所有子树的个数等于1 2 3构成的所有子树的个数(都是三个相邻数),从而s(4,1) = "左子树的个数" * "右子树的个数" = 1* F(3) = F(0)*F(3);
对于s(4,2):根节点2的左侧为1,即左子树的个数为1, 右侧为由“3 4”构成的所有子树,考虑到 3 4构成的所有子树的个数等于1 2 构成的所有子树的个数(都是2个相邻数),从而s(4,2) = "左子树的个数" * "右子树的个数" = 1* F(2) = F(1)*F(2);
。。。
从而得到:
s(4,1) = F(0)*F(1);
s(4,2) = F(1)*F(2);
s(4,3) = F(2)*F(1);
s(4,4) = F(3)*F(0);
记F(0) =1;F(1) =1;
从而:
F(4) = F(0)*F(3) + F(1)*F(2) + F(2)*F(1) + F(3)*F(0);
= sum( F(i)*F(3-i) ), i=0,1,2,3
F(n) = sum( F(i)*F(n-1-i) ), i=0,1,2,3,...,n-1
从而递归可解,递归终止条件是:F(0), F(1)
Code1:超时了
int numTrees(int n) {
if (n < 0)
return 0;
if (0 == n || 1 == n)
{
return 1;
}
int c = 0;
for (int i = 0; i <= n - 1; i++)
{
c += numTrees(i)*numTrees(n - 1 - i);
}
return c;
}
Code2: 将中间结果保存下来,就像斐波那契数的计算:击败了100%用户
class Solution {
public:
int numTrees(int n) {
if (n < 0)
return 0;
if (0 == n || 1 == n)
{
return 1;
}
//store the result to reduce time;
std::vector<int> vecNum;
vecNum.push_back(1);//0th
vecNum.push_back(1);//1th
for (int i = 2; i <= n; i++)
{
int c = 0;
for (int j = 0; j <= i - 1; j++)
{
c += vecNum[j]*vecNum[i - 1 - j];
}
vecNum.push_back(c);
}
return vecNum[n];
}
};
2: 找出所有二叉搜索树并打印
https://leetcode-cn.com/problems/unique-binary-search-trees-ii/