持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情.
96. 不同的二叉搜索树
题目描述
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
解题思路
假设 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)f(i)=G(i−1)∗G(n−i)
综合两个公式可以得到 卡特兰数 公式:
G(n)=G(0)∗G(n−1)+G(1)∗(n−2)+...+G(n−1)∗G(0)
思路一: 动态规划
动态规划转移方程如下:
G(n)=G(0)∗G(n−1)+G(1)∗(n−2)+...+G(n−1)∗G(0)
实现代码如下:
/**
* @param {number} n
* @return {number}
*/
var numTrees = function(n) {
let G = Array(n + 1).fill(0);
G[0] = 1;
G[1] = 1;
for(let i = 2; i <= n; i++)
for(let j = 1; j <= i; j++)
G[i] += G[j-1] * G[i-j];
return G[n];
};
-
时间复杂度 : O() ,其中 n 表示二叉搜索树的节点个数。G(n) 函数一共有 n 个值需要求解,每次求解需要 O(n) 的时间复杂度,因此总时间复杂度为 O()
-
空间复杂度 : O(n)
思路二: 数学公式
实现代码如下:
/**
* @param {number} n
* @return {number}
*/
var numTrees = function(n) {
let C = 1;
for (let i = 0; i < n; ++i) {
C = C * 2 * (2 * i + 1) / (i + 2);
}
return C;
};
- 时间复杂度 : O(n) ,其中 n 表示二叉搜索树的节点个数。我们只需要循环遍历一次即可。
- 空间复杂度 : O(1)