题目:给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
本题的关键点在于确定递推公式,由于二叉搜索树的性质,所以本题中拥有相同节点数的二叉树搜索树的数量是相同的。根据动态规划的做题顺序:
(1)动态规划数组和含义
dp[i] : 1到i为节点组成的二叉搜索树的个数为dp[i]
(2)递推公式
dp[i] += dp[j - 1] * dp[i - j]; ,j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量。j相当于是头结点的元素,从1遍历到i为止。
(3)初始化
由于j从1开始,所以只需要初始化dp[0]即可。
从定义上来讲,空节点也是一棵二叉树,也是一棵二叉搜索树。从递归公式上来讲,dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量] 中以j为头结点左子树节点数量为0,也需要dp[以j为头结点左子树节点数量] = 1。
所以初始化dp[0] = 1
(4)遍历顺序
本题需要双层for循环遍历,首先遍历节点数i,再遍历i里面每一个数作为头结点的状态,用j来遍历。
(5)举例推导dp数组
代码如下:
class Solution {
public:
int numTrees(int n) {
vector<int> dp(n + 1);
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
return dp[n];
}
};