以前说关于树的题都是DFS,BFS,其实树可以考察的东西还有很多。
题目链接:
不同的二叉搜索树 - 力扣(LeetCode)leetcode-cn.com题目描述:
给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
1 3 3 2 1
/ / /
3 2 1 1 3 2
/ /
2 1 2 3
解题思路:
首先,这种每一步可以在前一步的基础上去计算的题,我们一般用动态规划求解,它可以把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解。
对以动态规划,重点是要找到初始条件和递推公式。
本题中,显然初始条件即为 t[0]=1
和t[1]=1
,意味着当没有节点或者只有1个节点时,种类为1。
那递推公式是什么呢?我们不妨以 n 为 7 做例子,结果肯定是分别以1, 2, 3...7为根节点的数目之和。
那再以 3 作为根节点,会存在多少种情况呢。显然左子树节点包括1, 2,而右子树节点包括4, 5, 6, 7。所以以 3 作为根节点,二叉树数量等于2个节点能产生的二叉树数量乘以4个节点能产生的二叉树数量。
那依次类推,以其他数字为根节点能产生的二叉树数量也就可以得到了。
这里定义两个函数:
:长度为
的序列的不同二叉搜索树个数。
:以
为根的不同二叉搜索树个数
。
则有如下推论:
将(1), (2)两个公式结合,则有:
有了这个,写代码就很容易了。
代码如下:
class Solution {
public:
int numTrees(int n)
{
vector<int> t(n + 1, 0);
t[0] = t[1] = 1;
int i, j;
for(i = 2; i <= n; ++i)
{
for(j = 1; j <= i; ++j){
t[i] += t[j-1] * t[i-j];
}
}
return t[n];
}
};
如果有任何疑问,欢迎提出。如果有更好的解法,也欢迎告知。