「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战」
前言
力扣第九十六题 不同的二叉搜索树
如下所示:
给你一个整数 n
,求恰由 n
个节点组成且节点值从 1
到 n
互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 1:
1 | ini复制代码输入: n = 3 |
一、思路
这一题比上一题不同的是:只关心二叉搜素树的种树,而不关系树的节点了。
所以一开始我的思路也是用递归来做的,去除了保留路径的部分,仅得到左孩子的个数和右孩子的个数即可。7代码如下所示:
1 | java复制代码public int dfs(int start, int end) { |
但是很可惜,在 n=18
时会提示超出时间限制!
那既然不能用 递归
来自顶向下,那就只能使用 动态规划
来实现 自底向上
了。
首先我们先看一下 递归
中调用的地方,我们发现在递归中一直在求 1 ~ i-1
和 i+1 ~ n
左孩子和右孩子个数。
我们不妨设 dp[i]
为长度为 i
的不同二叉搜索树的个数。
可以有 dp[n] = dp[0]dp[n-1] + dp[1]dp[n-2] + dp[2]dp[n-3] + ... + dp[n-1]dp[0]
公式解释:
因为
dp[n]
就是选择1 ~ n
中的某一个元素i
为根,再将1 ~ i-1
中的元素作为左孩子,i+1 ~ n
中的元素作为右孩子。
dp[0]dp[n-1]
就表示选择了第一个元素作为根有多少种结果。此外,因为二叉搜索树的特殊性。对于
1, 2, 3
和1, 2, 4
组成的二叉搜索树的种数是相同的。所以我们在公式中可以忽略元素的值,而只关注元素的个数,因为相同元素个数组成的二叉搜索树的种树是相同的。
二、实现
实现代码
实现代码与思路中保持一致
1 | java复制代码 public int numTrees(int n) { |
测试代码
1 | java复制代码 public static void main(String[] args) { |
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~
本文转载自: 掘金