[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. JAVA基础之复识二

    JAVA语言 未经本人允许禁止转载或使用 基础知识:JAVA数据类型,运算符,流程控制等 注释: // 单行注释 /* 多行连续注释 ... */ /** 文档注释,该类型的注释会生成一个html文件 ...

  2. 力扣(LeetCode)453. 最小移动次数使数组元素相等

    给定一个长度为 n 的非空整数数组,找到让数组所有元素相等的最小移动次数.每次移动可以使 n - 1 个元素增加 1. 示例: 输入: [1,2,3] 输出: 3 解释: 只需要3次移动(注意每次移动 ...

  3. Python中什么是变量

    在Python中,变量的概念基本上和初中代数的方程变量是一致的. 例如,对于方程式 y=x*x ,x就是变量.当x=2时,计算结果是4,当x=5时,计算结果是25. 只是在计算机程序中,变量不仅可以是 ...

  4. SQL service 中的 ”输入SQL命令窗口“ 打开了 “属性界面” 回到 ”输入SQL命令窗口“

    输入SQL命令窗口点击上面的菜单栏中的 “窗口”

  5. Mac 如何安装 chromedriver

    1.使用brew  命令 前提是要安装 brew 这里不做介绍 使用命令 brew install chromedriver 如上图出现错误,根据提示可以使用如下命令安装 brew cask inst ...

  6. js插件---iCheck是用来做什么的

    js插件---iCheck是用来做什么的 一.总结 一句话总结:25 种参数 用来定制复选框(checkbox)和单选按钮(radio button) 定制复选框 定制单选按钮 1.iCheck常用的 ...

  7. PHP curl是什么

    PHP curl是什么 一.总结 一句话总结:PHP支持的由Daniel Stenberg创建的libcurl库允许你与各种的服务器使用各种类型的协议进行连接和通讯. libcurl库 允许你与各种的 ...

  8. 开发者说 | Apollo控制算法之汽车动力学模型和LQR控制

    参考:https://mp.weixin.qq.com/s?__biz=MzI1NjkxOTMyNQ==&mid=2247486444&idx=1&sn=6538bf1fa74 ...

  9. Getting Started with Processing 第二,三章总结

    第一章是文化熏陶. 第二章:开始编程 菜单栏中的 Show 的快捷键 Run:进行显示shortcut:可以通过快捷键 cmd + R 执行Present:进行全屏的显示shortcut:可以通过按下 ...

  10. 20165327 2017-2018-2 《Java程序设计》第9周学习总结

    20165327 2017-2018-2 <Java程序设计>第9周学习总结 教材内容总结 第十三章 (一)教材学习内容总结 理解 URL类是对统一资源定位符的抽象,使用URL创建对象的应 ...