[Leetcode] Unique binary search trees 唯一二叉搜索树

Unique Binary Search Trees leetcode java

描述

Given n, how many structurally unique BST's (binary search trees) that store values 1...n?

For example,
Given n = 3, there are a total of 5 unique BST's.

   1         3     3      2      1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3

解析

递归

思路:空树和只有根节点时,也为BST。对于一点i,当其为根节点时,左子树的节点的个数为i-1,(为1,...i-1),右子树的个数为n-i(为,i+1,...n)。对一个根来说,唯一二叉树的个数为左子树结点的个数乘以右子树的个数。而根节点可以从1到n 中选择。

可行的二叉查找树的数量,其实二叉查找树可以任意取根,只要满足中序遍历有序的要求就可以。从处理子问题的角度来看,选取一个结点为根,就把结点切成左右子树,以这个结点为根的可行二叉树数量就是左右子树可行二叉树数量的乘积,所以总的数量是将以所有结点为根的可行结果累加起来。

动态规划

这是Catalan Number卡特兰数的一个例子。卡特兰数的的递推公式:

根据图示

以1为根的树有几个,完全取决于有二个元素的子树有几种。同理,2为根的子树取决于一个元素的子树有几个。以3为根的情况,则与1相同。

定义Count[i] 为以[0,i]能产生的Unique Binary Tree的数目,

如果数组为空,毫无疑问,只有一种BST,即空树,
    Count[0] =1

如果数组仅有一个元素{1},只有一种BST,单个节点
    Count[1] = 1

如果数组有两个元素{1,2}, 那么有如下两种可能
    1                       2
     \                    /
       2                1
    Count[2] = Count[0] * Count[1]   (1为根的情况)
                  + Count[1] * Count[0]  (2为根的情况。

再看一遍三个元素的数组,可以发现BST的取值方式如下:
    Count[3] = Count[0]*Count[2]  (1为根的情况)
                  + Count[1]*Count[1]  (2为根的情况)
                  + Count[2]*Count[0]  (3为根的情况)

所以,由此观察,可以得出Count的递推公式为
    Count[i] = ∑ Count[0...k] * [ k+1....i]     0<=k<i-1
    问题至此划归为一维动态规划。

[Note]
    这是很有意思的一个题。刚拿到这题的时候,完全不知道从那下手,因为对于BST是否Unique,很难判断。最后引入了一个条件以后,立即就清晰了,即
    当数组为 1,2,3,4,.. i,.. n时,基于以下原则的BST建树具有唯一性:
   以i为根节点的树,其左子树由[1, i-1]构成, 其右子树由[i+1, n]构成。

维护量res[i]表示含有i个结点的二叉查找树的数量。

根据上述递推式依次求出1到n的的结果即可。

用一个数组保存 1 至 n-1 对应的不同二叉树的个数 X1、X2、X3、... Xn-1,

则 n 对应的不同二叉树个数Xn = Xn-1 + X1*Xn-2 + X2*Xn-3 + X3*Xn-4 + ... + Xn-2*X1 + Xn-1

通过这个递推式,我们可以从 N = 1 开始递推,最后得到 N = n 时不同二叉查找树的个数。

时间上每次求解i个结点的二叉查找树数量的需要一个i步的循环,总体要求n次,所以总时间复杂度是O(1+2+...+n)=O(n^2)。空间上需要一个数组来维护,并且需要前i个的所有信息,所以是O(n)。

代码

递归

class Solution {
public int numTrees(int n) {
if (n == 0 || n == 1) {
return 1;
}
int sum = 0;
for(int i = 1; i <= n; ++i) {
sum += numTrees(i - 1) * numTrees(n - i);
}
return sum;
}
}

动态规划

class Solution {
public int numTrees(int n) {
if (n <= 0)
return 0;
int[] res = new int[n + 1];
res[0] = 1;
res[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 0; j < i; j++) {
res[i] += res[j] * res[i - j - 1];
}
}
return res[n];
}
}

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

  1. [leetcode]96. Unique Binary Search Trees给定节点形成不同BST的个数

    Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n? Input: ...

  2. [LeetCode] 96. Unique Binary Search Trees 唯一二叉搜索树

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  3. [LeetCode] 95. Unique Binary Search Trees II(给定一个数字n,返回所有二叉搜索树) ☆☆☆

    Unique Binary Search Trees II leetcode java [LeetCode]Unique Binary Search Trees II 异构二叉查找树II Unique ...

  4. 52. leetcode 96. Unique Binary Search Trees

    96. Unique Binary Search Trees Given n, how many structurally unique BST's (binary search trees) tha ...

  5. leetcode 96. Unique Binary Search Trees 、95. Unique Binary Search Trees II 、241. Different Ways to Add Parentheses

    96. Unique Binary Search Trees https://www.cnblogs.com/grandyang/p/4299608.html 3由dp[1]*dp[1].dp[0]* ...

  6. [LeetCode] 96. Unique Binary Search Trees 独一无二的二叉搜索树

    Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n? Example ...

  7. leetcode 96 Unique Binary Search Trees ----- java

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  8. Java [Leetcode 96]Unique Binary Search Trees

    题目描述: Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For ...

  9. [leetcode] 96 Unique Binary Search Trees (Medium)

    原题 字母题 思路: 一开始妹有一点思路,去查了二叉查找树,发现有个叫做卡特兰数的东西. 1.求可行的二叉查找树的数量,只要满足中序遍历有序. 2.以一个结点为根的可行二叉树数量就是左右子树可行二叉树 ...

随机推荐

  1. HTML XHTML HTNL5 简介

    XHTML 是HTML与XML(扩展标记语言)的结合物 包含了所有与XML语法结合的HTML 4.01元素 XHTML 指可扩展超文本标签语言(EXtensible HyperText Markup ...

  2. shell中的${},##, %% , :- ,:+, ? 的使用

    假设我们定义了一个变量为:file=/dir1/dir2/dir3/my.file.txt 可以用${ }分别替换得到不同的值:${file#*/}:删掉第一个/ 及其左边的字符串:dir1/dir2 ...

  3. gzip: stdin: not in gzip format tar: Child returned status 1 tar: Error is not recoverable: exiting now

    [root@Gris- FMIS2600bak]# tar -zxvf /home/oradata/FMIS2600DMP.tar.gz gzip: stdin: not in gzip format ...

  4. Python安装常见问题:ModuleNotFoundError: No module named '_ctypes' 解决办法

    一般位于3.7以上版本编译安装时出错 缺少依赖包libffi-devel 在安装3.7以上版本时,需要一个新的libffi-devel包做依赖 解决方法: yum install libffi-dev ...

  5. strpos检测字符串是否包含元素

    <?php echo strpos('https://www.baidu.com','https',0); ?> 默认的第三个参数就是0. 第三个参数表示查找的起始位置. 如果不存在的话, ...

  6. 前端阶段_div以及css介绍

    1.div div是html的一个标签,是块级元素,单独使用没有意义,必须结合css来使用,进行网页布局 2.span span是一个html标签,是一个内联元素,主要对括起来的内容进行修饰 3.&l ...

  7. Qt532.QSettings_默认分隔符

    1.http://bbs.csdn.net/topics/391831509?page=1 2楼: QSettings读取配置文件的内容是以逗号作为分隔符,以分号作为结束符.遇到分号就结束了,后面的内 ...

  8. 要使用myConfig.properties配置文件作为实体类的映射文件的话,格式要用=,最关键的要和实例类中通过反射获取值的KEY要一样,不样会反射取不到值

    ABC=https://fsdfsdf.iy.comABCId=L2345345ZhP345ABCKey=sfdf4234f234dhE6Ut0aABCName=Gassd010 上面是myConfi ...

  9. 《剑指offer》第六十二题(圆圈中最后剩下的数字)

    // 面试题62:圆圈中最后剩下的数字 // 题目:0, 1, …, n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里 // 删除第m个数字.求出这个圆圈里剩下的最后一个数字. #inclu ...

  10. Android 虹软免费人脸识别 SDK开发

    目前我们的应用内使用了 ArcFace 的人脸检测功能,其他的我们并不了解,所以这里就和大家分享一下我们的集成过程和一些使用心得集成ArcFace FD 的集成过程非常简单在 ArcFace FD 的 ...