LeetCode 96——不同的二叉搜索树
1. 题目
2. 解答
以 \(1, 2, \cdots, n\) 构建二叉搜索树,其中,任意数字都可以作为根节点来构建二叉搜索树。当我们将某一个数字作为根节点后,其左边数据将构建为左子树,右边数据将构建为右子树。因此,这是一个递归问题。
若以第 \(i\) 个数据为根节点,其左边数据有 \(i-1\) 个,左子树可能情况为 left_num,右边数据有 \(n-i\) 个,右子树可能情况为 right_num,因此以当前数据为根节点可以构建出 left_num * right_num 个二叉搜索树。
所以,我们要做的就是遍历 \(i = 1\cdots n\),统计出每个数据作为根节点可以构建出的二叉搜索树总个数即可。
- 递归法
class Solution {
public:
int numTrees(int n) {
int sum = 0;
if (n <= 1) return 1;
// 以当前的数为根节点,左右两边的数分别构建子树
for (int i = 1; i <= n; i++)
{
int left_num = numTrees(i - 1); // 左边的数可以构建多少个二叉搜索树
int right_num = numTrees(n - i); // 右边的数可以构建多少个二叉搜索树
sum += left_num * right_num;
}
return sum;
}
};
但是上面的程序运行时超时了,其实我们只需要统计一半数据就可以了,因为两边是对称的。
比如我们有 1,2,3,4,5 五个数,以 2 作为根节点,左边有 1 个数,右边有 3 个数。以 4 作为根节点,左边有 3 个数,右边有 1 个数。这两种情况是一样的,因此如果数据个数为偶数,我们只需要统计一半数据即可,而为奇数的话我们就要再多统计一个中间数据。
class Solution {
public:
int numTrees(int n) {
int sum = 0;
if (n <= 1) return 1;
int is_odd = n % 2;
int mid = n / 2;
// 以当前的数为根节点,左右两边的数分别构建子树
for (int i = 1; i <= mid; i++)
{
int left_num = numTrees(i - 1); // 左边的数可以构建多少个二叉搜索树
int right_num = numTrees(n - i); // 右边的数可以构建多少个二叉搜索树
sum += left_num * right_num;
}
sum = sum * 2;
if (is_odd) sum = sum + numTrees(mid) * numTrees(n - mid - 1);
return sum;
}
};
此外,我们还可以定义一个全局变量,来存放已经计算过的数值,避免在递归过程中大量地重复计算。
class Solution {
public:
#define MAX 1000
int nums[MAX]; // 存放已经计算过的数值
int numTrees(int n) {
int sum = 0;
//if (n <= 0) return 1;
if (n <= 1) return 1;
// 以当前的数为根节点,左右两边的数分别构建子树
for (int i = 1; i <= n; i++)
{
if (nums[i-1] == 0) nums[i-1] = numTrees(i - 1); // 左边的数可以构建多少个二叉搜索树
int left_num = nums[i-1];
if (nums[n-i] == 0) nums[n-i] = numTrees(n - i); // 右边的数可以构建多少个二叉搜索树
int right_num = nums[n-i];
sum += left_num * right_num;
}
return sum;
}
};
- 迭代法
还可以将递归改写为循环,避免函数多次调用执行效率较低。
class Solution {
public:
int numTrees(int n) {
int nums[n+1] = {0};
nums[0] = 1;
nums[1] = 1;
if (n <= 1) return 1;
for (int i = 2; i <= n; i++)
{
// 从 n=2 开始统计可以构建多少个不同的二叉搜索树
for (int j = 1; j <= i; j++)
{
nums[i] += nums[j-1] * nums[i-j];
}
}
return nums[n];
}
};
获取更多精彩,请关注「seniusen」!
LeetCode 96——不同的二叉搜索树的更多相关文章
- Java实现 LeetCode 96 不同的二叉搜索树
96. 不同的二叉搜索树 给定一个整数 n,求以 1 - n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 ...
- Leetcode 96. 不同的二叉搜索树
题目链接 https://leetcode.com/problems/unique-binary-search-trees/description/ 题目描述 给定一个整数 n,求以 1 ... n ...
- [LeetCode]96. 不同的二叉搜索树(DP,卡特兰数)
题目 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ ...
- LeetCode 96. 不同的二叉搜索树(Unique Binary Search Trees )
题目描述 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 输出: 解释: 给定 n = , 一共有 种不同结构的二叉搜索树: \ / / / \ \ / / ...
- LeetCode 96 - 不同的二叉搜索树 - [DP]
假定 $f[n]$ 表示有 $n$ 个节点的二叉树,有多少种不同结构. 因此 $f[n] = \sum_{i=0}^{n-1} (f[i] \times f[n-1-i])$,选一个节点作为根节点,那 ...
- Leetcode:96. 不同的二叉搜索树
Leetcode:96. 不同的二叉搜索树 Leetcode:96. 不同的二叉搜索树 题目在链接中,点进去看看吧! 先介绍一个名词:卡特兰数 卡特兰数 卡特兰数Cn满足以下递推关系: \[ C_{n ...
- 【JavaScript】Leetcode每日一题-二叉搜索树的范围和
[JavaScript]Leetcode每日一题-二叉搜索树的范围和 [题目描述] 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例1: 输入: ...
- 【python】Leetcode每日一题-二叉搜索树节点最小距离
[python]Leetcode每日一题-二叉搜索树节点最小距离 [题目描述] 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 . 示例1: 输入:root = [4 ...
- Leetcode题目96.不同的二叉搜索树(动态规划-中等)
题目描述: 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 ...
随机推荐
- oracle cascade用法
原文地址:https://www.cnblogs.com/moyijian/p/9940323.html#4111551 级联删除,比如你删除某个表的时候后面加这个关键字,会在删除这个表的同时删除和该 ...
- python环境Anaconda的安装
本人最开始的的环境为:win10 + 32位的python 最近想学习一下爬虫,听说某些库需要64的python才能实现(本人也是小白,只是平时喜欢折腾,这里是听说,暂时没有能力解释),无奈之下只好卸 ...
- css 自定义checkbox多选复选框样式
html: <input type="checkbox" id="" value="">菜单1 <input type=& ...
- Spring的绿草丛
Spring 轻量级框架,JavaEE的春天,当前主流框架 “站立式”的企业应用开发框架 目标 实现有的技术更加易用,推进编码最佳实践 内容:loC容器,AOP实现,数据访问支持:简化JDBC/ORM ...
- mysql 操作表结构
整理一下对mysql表结构的简单操作,dos窗口模式的,现在基本上都是些图形化操作mysql,像这种命令形式的少了很多,暂时记忆点,以防以后忘记. 从数据库的创建开始: show databases; ...
- hadoop生态搭建(3节点)-09.flume配置
# http://archive.apache.org/dist/flume/1.8.0/# ===================================================== ...
- hadoop的自定义分组实现 (Partition机制)
hadoop开发中我们会遇到类似这样的问题,比如 如何将不同省份的手机号分别输出到不同的文件中,本片文章将对hadoop内置的Partition类进行重写以解决这个问题. MapReduce的使用者通 ...
- Python2018秋招(笔者亲身经历)
毕业即失业,苦逼的大四狗伤不起哟. 又到了一年一度的秋招了,笔者也在拉勾,智联,boss直聘注册了,投了50份简历,3个面试,然而全挂了. 笔者痛定思痛决定将自己的经历贴出,希望可以帮到要面试的同学. ...
- python神坑系列之深浅拷贝
深浅拷贝 1.注意在拷贝中只有使用了.deepcopy方法才能进行深度拷贝!其余的一律是浅拷贝 #深拷贝import copy lst = copy.deepcopy(lst1) 浅拷贝: 拷贝的是 ...
- 【转】I2C总线相关知识
1. I2C access 1.1. I2C introduction I2C(Inter-Integrated Circuit)总线是由NXP恩智浦半导体公司在80年代开发的两线式串行总线,用来进行 ...