题目一:给出一个n,代表有从1到n的数字[1,2,3,··· n],问可以构成多少种二叉搜索树?
题目一:给出一个n,代表有从1到n的数字[1,2,3,··· n],问可以构成多少种二叉搜索树?
一开始的想法是直接递归构造,时间复杂度是指数上升;
后来想法是找规律:
先看例子:
n = 1, 有一个元素,可以构成一个二叉搜索树,左右都没有元素,总数量 = 左子树数量 右子树数量,记为f(1) = f(0) f(0) = 1,这儿可以将f(0)初始化为1;
n = 2, 1做根,那么左子树没有元素记为f(0),右子树有一个元素记为f(1), 2做根,左子树有一个元素,记为f(1),右子树没有元素记为f(0);
总共:f(2) = f(0) f(1) + f(1) f(0) = 2;
n = 3, 1做根,数量 = f(0) f(2), 2做根 数量 = f(1) f(1), 3做根, 数量 = f(2) f(0);
总共 f(3) = f(0) f(2) + f(1) f(1) + f(2) f(0) = 5;
可以看出f(n),依赖与f(0)到f(n-1),换句话说可以有前面的n-1项推导出第n项;
分析关系表达式:
记h(k)为以k为根可以生成的二叉搜索树数量;
当以k为根时,他的左子树为[1,2 ··· k-1]构成,也就是左子树有k-1个元素构成,这个就可以记为f(k-1);
右子树为[k+1 ··· n]构成,也就是右子树有n-k个元素构成,这个可以记为f(n-k);
那么h(k) = f(k-1) * f(n-k); 要记得k的范围可以从1到n;
整合以上规律可得到:有n个元素的二叉搜索树的数量;f(n) = h(1)+h(2)+···+h(n) = ∑ h(k) ,0 < k <= n;
又因为h(k) = f(k-1) f(n-k)得到:f(n) = ∑ f(k-1) f(n-k); 0 < k <= n;
代码:输入n,输出可以构造出的二叉搜索树的数量;
时间复杂度O(n^3);
private static int BSCount(int n) {
int[] res = new int[n+1];
res[0] = 1;
for(int i = 1; i<=n; i++) {
for(int k=1; k<=i; k++) {
res[i] += res[k-1] * res[i-k];
// System.out.println(i + " k:" + k +" " + res[i]);
}
}
return res[res.length-1];
}
注释:第一个循环用来控制根节点肯能出现的情况。因为这是一个递归表达式,第二个循环是用来控制计算以当下值为根节点的时候,所以依赖的前面表达式的值是多少。
比如计算以当n3的时候,需要计算一下三种情况:
res[3]+=res[0]*res[2] (以1为根节点时)
res[3]+=res[1]*res[1] (以2为根节点时)
res[3]+=res[2]*res[0] (以3为根节点时)
那么,这些表达式中的res[1]和res[2]需要提前计算。这个是由第二个循环来完成的。
题目一:给出一个n,代表有从1到n的数字[1,2,3,··· n],问可以构成多少种二叉搜索树?的更多相关文章
- c语言题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点
//题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小.也可能没有鞍点. // #include "stdio.h" #include <stdli ...
- 【剑指Offer面试编程题】题目1503:二叉搜索树与双向链表--九度OJ
题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为一个 ...
- 九度oj 题目1009:二叉搜索树
题目1009:二叉搜索树 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5733 解决:2538 题目描述: 判断两序列是否为同一二叉搜索树序列 输入: 开始一个数n,(1<=n&l ...
- 九度oj题目1009:二叉搜索树
题目描述: 判断两序列是否为同一二叉搜索树序列 输入: 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接 ...
- 九度oj 题目1367:二叉搜索树的后序遍历序列
题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 输入: 每个测试案例包括2行: 第一行为1个整数 ...
- 【剑指Offer面试编程题】题目1367:二叉搜索树的后序遍历序列--九度OJ
题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 输入: 每个测试案例包括2行: 第一行为1个整数 ...
- LeetCode 95 | 构造出所有二叉搜索树
今天是LeetCode专题第61篇文章,我们一起来看的是LeetCode95题,Unique Binary Search Trees II(不同的二叉搜索树II). 这道题的官方难度是Medium,点 ...
- [Jobdu] 题目1367:二叉搜索树的后序遍历序列
题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 输入: 每个测试案例包括2行: 第一行为1个整数 ...
- [LeetCode] 96. Unique Binary Search Trees(给定一个数字n,有多少个唯一二叉搜索树) ☆☆☆
[Leetcode] Unique binary search trees 唯一二叉搜索树 Unique Binary Search Trees leetcode java 描述 Given n, h ...
随机推荐
- day11 函数和命名空间
# def my_sum(*args):# sum_2=0# for i in args:# sum_2+=i# return sum_2### ret=my_sum(1,2,3,4)# print( ...
- TCP/IP 网络结构
- Linux信号signal处理机制
信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 ...
- 2062326 齐力锋 实验四《Java面向对象程序设计Android开发》实验报告
北京电子科技学院(BESTI) 实 验 报 告 课程: 程序设计与数据结构 班级: 1623 姓名: 齐力锋 学号: 20162326 成绩: 指导教师: 娄嘉鹏/王志强 实验日期: 2017年5 ...
- React Native混合开发中必须要学会点FlexBox布局
在前面的案例中,界面的搭建都是采用CSS的布局,基于盒子模型,依赖 display属性 , position属性, float属性.但对于那些特殊布局非常不方便,比如,垂直居中. 一种全新的针对web ...
- Linux系统下Git操作命令整理
1.显示当前的配置信息 git config --list 2. 创建repo从别的地方获取 git clone git://git.kernel.org/pub/scm/git/git.git 自己 ...
- spring security使用数据库验证的逻辑处理
前面做了多个示例,包括使用jdbc和hibernate两种方式访问数据库获取用户信息和权限信息,其中一些关键步骤如下: 我们在SecurityConfig中配置覆盖configure方法时候,可以 ...
- Servlet容器初始化IOC容器
<!-- ServletContext参数,配置Ioc容器的xml文件名 --> <context-param> <param-name>contextConfig ...
- PHP正则表达式 /i, /is, /s, /isU等 都是些什么东西呢?
PHP正则表达式 /i, /is, /s, /isU等 都是些什么东西呢? i 不区分大小写 s 模式中的圆点元字符(.)匹配所有的字符,包括换行符 x 模式中的空白字符除了被转义的或在字符类中的以外 ...
- ThinkPHP3.2添加scws中文分词
前言 前一段时间,公司网站做站内搜索,只简单针对输入的文字进行搜索,作全匹配检索,搜索出来的内容很少.如何达到模糊搜索,匹配到更多的内容成了需要解决的问题.于是,今天想到可以做分词检索,如何对输入的一 ...