96. 不同的二叉搜索树
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 1:
输入:n = 3
输出:5
示例 2:
输入:n = 1
输出:1
提示:
1 <= n <= 19
解题
方法一: 动态规划
假设 n 个节点存在二叉排序树的个数是 G (n),令 f(i) 为以 i 为根的二叉搜索树的个数,则
G(n)=f(1)+f(2)+f(3)+f(4)+…+f(n)
当 i 为根节点时,其左子树节点个数为 i-1 个,右子树节点为 n-i,则
f(i)=G(i−1)∗G(n−i)
所以
G(n)=G(0)∗G(n−1)+G(1)∗(n−2)+…+G(n−1)∗G(0)
class Solution {
// 动态规划
public int numTrees(int n) {
// 初始化函数:表示种数
int[] dp = new int[n+1];
// 初始化值
dp[0] = 1;
dp[1] = 1;
// 填充整个
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j-1] * dp[i-j];
}
}
return dp[n];
}
}
方法二:数学
时间复杂度 : O(n)
空间复杂度 : O(1)
事实上我们在方法一中推导出的函数的值在数学上被称为卡塔兰数
卡塔兰数更便于计算的定义如下:
C0=1, Cn+1=2(2n+1) / (n+2) * Cn
class Solution {
public int numTrees(int n) {
// 提示:我们在这里需要用 long 类型防止计算过程中的溢出
long C = 1;
for (int i = 0; i < n; ++i) {
C = C * 2 * (2 * i + 1) / (i + 2);
}
return (int) C;
}
}