「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。
题目
链接:leetcode-cn.com/problems/un…
给你一个整数 n
,求恰由 n
个节点组成且节点值从 1
到 n
互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 1:
**输入:**n = 3 **输出:**5
示例 2:
**输入:**n = 1 **输出:**1
提示:
1 <= n <= 19
思路
刚看到题目一开始想到的是排列组合问题,后来发现规律难寻就画出如下草图,然后花了一分钟搞定了。
1.对于整数n,互不相同的二叉搜索数量 = 所有以1到n为根节点的组合数量之和。
2.以i为根节点的组合数量 = 左子树节点组合数 * 右子树节点组合数。
假设我们要求当给定的整数n为5时的组合数。
1.我们要枚举以1,2,3,4,5为根节点的组合数量,将每一种情况的组合数相加就是最终结果。
2.假设此时要求以2为根节点的组合数量。根据二叉搜索树的定义,左子树上的节点数量为1(比2小的只有1),右子树上的节点数量是3(比2大的有3,4,5)。那么以2为根节点的组合数量 = 节点数量为1时的组合数 * 节点数量为3时的组合数。
那么怎么知道节点数量为i时的组合数呢,我们可以直接定义:当节点数量为i时,互不相同的二叉搜索树为dp[i]。
当根节点为2时,组合数 = dp[1] * dp[3];
所以状态转移方程就直接出来了 dp[i] = dp[左侧节点数量] * dp[右侧节点数量]
考虑最简单的情况:当n=0时,dp[0] = 1(无为而治,没有节点也是一种组合)
代码
function numTrees(n: number): number {
const dp = new Array(n).fill(0);
dp[0] = 1;
for(let i = 1;i < dp.length;i++){
for(let j = 0;j < i;j++){
dp[i] += (dp[j] * dp[i - j - 1]);
}
}
return dp[n];
};
思路
- n个数的解是可以利用的
- n + 1的解,就是循环 1 -- n+1,然后计算
var numTrees = function (n) {
let map = [1, 1];
for (let i = 2; i <= n; i++) {
let num = 0;
for (let a = 1; a <= i; a++) {
num += map[a - 1] * map[i - a];
}
map[i] = num;
}
return map[n];
};