题目描述:
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
思考
- dp[n]:表示n个节点组成的二叉搜索树的种数
- 递推公式:
- 当n=1与n=2时:dp[1]=1,dp[2]=2
- 当n=3时:
dp[3]=元素1为头结点搜索树的数量 + 元素2为头结点搜索树的数量 + 元素3为头结点 搜索树的数量,其中:
- 当n=1与n=2时:dp[1]=1,dp[2]=2
元素1为头结点搜索树的数量 = 右⼦树有2个元素的搜索树数量 * 左⼦树有0个元素的搜索树数量
元素2为头结点搜索树的数量 = 右⼦树有1个元素的搜索树数量 * 左⼦树有1个元素的搜索树数量
元素3为头结点搜索树的数量 = 右⼦树有0个元素的搜索树数量 * 左⼦树有2个元素的搜索树数量
有2个元素的搜索树数量就是dp[2]。
有1个元素的搜索树数量就是dp[1]。
有0个元素的搜索树数量就是dp[0]。
所以dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2]
在上⾯的分析中,其实已经看出其递推关系,dp[i] += dp[以j为头结点左⼦树节点数量] dp[以j为头结点右⼦树节点数量]
j相当于是头结点的元素,从1遍历到i为⽌。
所以递推公式:dp[i] += dp[j - 1] * dp[i - j],j-1 为j为头结点左⼦树节点数量,i-j 为以j为 头结点右⼦树节点数量
- 初始化:dp[0]=1,空二叉树也是一种二叉树,推导的基础是dp[0]
- 遍历顺序:想要得到dp[i],得先得到dp[j-1],dp[i-j],故遍历顺序为,i=1至n,j=1至i
- 打印dp数组
代码
var numTrees = function(n) {
//初始化
var dp=new Array(n+1).fill(0);
dp[0]=1;
//根据递推公式得到dp数组
for(let i=1;i<=n;i++){
for(let j=1;j<=i;j++){
dp[i]+=dp[j-1]*dp[i-j];
}
}
return dp[n]
}
结果