题目一:给出一个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],问可以构成多少种二叉搜索树?的更多相关文章

  1. c语言题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点

    //题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小.也可能没有鞍点. // #include "stdio.h" #include <stdli ...

  2. 【剑指Offer面试编程题】题目1503:二叉搜索树与双向链表--九度OJ

    题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为一个 ...

  3. 九度oj 题目1009:二叉搜索树

    题目1009:二叉搜索树 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5733 解决:2538 题目描述: 判断两序列是否为同一二叉搜索树序列 输入: 开始一个数n,(1<=n&l ...

  4. 九度oj题目1009:二叉搜索树

    题目描述: 判断两序列是否为同一二叉搜索树序列 输入:                        开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接 ...

  5. 九度oj 题目1367:二叉搜索树的后序遍历序列

    题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 输入: 每个测试案例包括2行: 第一行为1个整数 ...

  6. 【剑指Offer面试编程题】题目1367:二叉搜索树的后序遍历序列--九度OJ

    题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 输入: 每个测试案例包括2行: 第一行为1个整数 ...

  7. LeetCode 95 | 构造出所有二叉搜索树

    今天是LeetCode专题第61篇文章,我们一起来看的是LeetCode95题,Unique Binary Search Trees II(不同的二叉搜索树II). 这道题的官方难度是Medium,点 ...

  8. [Jobdu] 题目1367:二叉搜索树的后序遍历序列

    题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 输入: 每个测试案例包括2行: 第一行为1个整数 ...

  9. [LeetCode] 96. Unique Binary Search Trees(给定一个数字n,有多少个唯一二叉搜索树) ☆☆☆

    [Leetcode] Unique binary search trees 唯一二叉搜索树 Unique Binary Search Trees leetcode java 描述 Given n, h ...

随机推荐

  1. 使用sqoop把mysql数据导入hive

    使用sqoop把mysql数据导入hive export HADOOP_COMMON_HOME=/hadoop export HADOOP_MAPRED_HOME=/hadoop   cp /hive ...

  2. Java并发之Semaphore的使用

    Java并发之Semaphore的使用 一.简介 今天突然发现,看着自己喜欢的球队发挥如此的棒,然后写着博客,这种感觉很爽.现在是半场时间,就趁着这个时间的空隙,说说Java并发包中另外一个重量级的类 ...

  3. 20165101刘天野 2018-2019-2《网络对抗技术》Exp2 后门原理与实践

    目录 20165101刘天野 2018-2019-2<网络对抗技术>Exp2 后门原理与实践 1. 实验内容 1.1 使用netcat获取主机操作Shell,cron启动 1.2 使用so ...

  4. React Native常用组件之TabBarIOS、TabBarIOS.Item组件、Navigator组件、NavigatorIOS组件、React Navigation第三方

    以下内容为老版本React Native,faceBook已经有了新的导航组件,请移步其他博客参考>>[我是传送门] 参考资料:React Navigation  react-native ...

  5. TCP的握手与挥手

    轻轻的TCP走了,正如TCP轻轻的来,TCP挥一挥手,传递了不知多少信息 看到哪,记到哪,想起哪,就看哪,这就是我的博客园,很随性 ---------------------------------- ...

  6. tyvj 1091 等差数列 dp

    P1091 等差数列 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 广东汕头聿怀初中 Train#3 Problem 3 描述 等差数列的定义是一个数列S, ...

  7. python测试函数的使用时间

    1. 使用装饰器来衡量函数执行时间 有一个简单方法,那就是定义一个装饰器来测量函数的执行时间,并输出结果:(代码通用3.x) import time from functools import wra ...

  8. mysql升级的一些踩坑点

    升级的方法一般有两类: 1.利用mysqldump来直接导出sql文件,导入到新库中,这种方法最省事也最保险 缺点:大库的mysqldump费时费力. 2.直接替换掉 mysql 的安装目录和 my. ...

  9. ubuntu16.04 添加中文ibus输入法

    ubuntu版本 16.04 在terminal  输入命令 sudo apt-get install ibus-pinyin sudo apt-get ibus-setup 设置 选择拼音,添加选择 ...

  10. linux下如何上传和下载文件

    一. 安装工具包rz及sz lrzsz是一个unix通信套件提供的X,Y,和ZModem文件传输协议,可以用在windows与linux 系统之间的文件传输,体积小速度快 yum install -y ...