【LeetCode】96. 不同的二叉搜索树

思路

个人的一些思考:
看完别人提供给的解题思路,对这道题目自己一开始的想法是,把所有的BST树的组合统计出来,而看到下面的解法,感觉并没有利用到题目中提到的BST的特性,主要是通过卡特兰数公式进行了求解

在这里插入图片描述
参考自灵魂画手的题解

下面是自己关于上述的解释
过程:
1、要获得以当前值为根节点的二叉树个数,如果知道了左子树和右子树的二叉树种类数 ,那我当前的结果只需要把左右子树的二叉树种类相乘即可。
因此,假设函数** f(i)** 表示以节点n为根的二叉搜索树的个数

2、为了表达f(),我们需要定义n个节点拥有二叉搜索树的个数的函数,因此,假设这个函数为G(n),则可以知道G(n) = f(1)+f(2)+…+f(n),即等于以任何一个节点为根节点的二叉搜索树的个数和

3、同样的,当i为根节点时,我们可以推导到,左子树节点个数为i-1个,则其拥有二叉搜索树的个数为G(i-1)右子树节点个数为n-i,则其拥有二叉搜索树的个数为G(n-i)。则以i为根节点的二叉搜索树的个数为f(i) = 左子树的二叉树的种类数目 * 右子树的二叉树的种类数目,即f(i) = G(i-1)*G(n-i)

4、可以发现这个转移方程是两步进行的,合并可以得到关于G的最终的动态转移方程
G(n) = G(0)G(n-1)+G(1)G(n-1)+G(2)G(n-2)…+G(n-1)G(0);

该公式称之为卡特兰数
而初始值为dp[0]=0,dp[1]=1。

5、因此,实现代码需要对长度为n的数组的每一个节点进行遍历,使其为根节点,其次是遍历子树的长度,合并结果,最终的dp[n]即为我们要求的结果。

代码

class Solution {
public:
	int numTrees(int n) {
		vector<int> dp(n + 1);
		//初始值
		dp[0] = 1;
		dp[1] = 1;
		for (int i=2;i<n+1;i++)
		{
			for (int j=1;j<i+1;j++)
			{
				//状态转移
				//卡特兰数公式
				dp[i] += dp[j - 1] * dp[i - j];
			}
		}
		return dp[n];
	}
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值