Title

给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?

示例:

输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:

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

动态规划

Solve

给定一个有序序列 1⋯n,为了构建出一棵二叉搜索树,我们可以遍历每个数字 i,将该数字作为树根,将 1⋯(i−1) 序列作为左子树,将 (i+1)⋯n 序列作为右子树,接着按照同样的方式递归构建左子树和右子树。

在上述构建的过程中,由于根的值不同,因此能保证每棵二叉搜索树是唯一的。由此可见,原问题可以分解成规模较小的两个子问题,且子问题的解可以复用。

题目要求是计算不同二叉搜索树的个数。为此,可以定义两个函数:

  1. G(n): 长度为 n 的序列能构成的不同二叉搜索树的个数。
  2. F(i,n): 以 i 为根、序列长度为 n 的不同二叉搜索树个数 (1≤i≤n)。

可见,G(n) 是我们求解需要的函数。

稍后我们将看到,G(n) 可以从 F(i, n) 得到,而 F(i, n) 又会递归地依赖于 G(n)。

首先,根据上一节中的思路,不同的二叉搜索树的总数 G(n),是对遍历所有(1≤i≤n)的 F(i, n) 之和。换言之:

∑i=1nF(i,n)\sum_{i=1}^{n}F(i,n)i=1∑n​F(i,n)

对于边界情况,当序列长度为 1(只有根)或为 0(空树)时,只有一种情况,即:

G(0)=1,G(1)=1G(0)=1,G(1)=1G(0)=1,G(1)=1

给定序列 1⋯n,我们选择数字 i 作为根,则根为 i 的所有二叉搜索树的集合是左子树集合和右子树集合的笛卡尔积,对于笛卡尔积中的每个元素,加上根节点之后形成完整的二叉搜索树,如下图所示:


举例而言,创建以 3 为根、长度为 7 的不同二叉搜索树,整个序列是 [1, 2, 3, 4, 5, 6, 7],我们需要从左子序列 [1, 2] 构建左子树,从右子序列 [4, 5, 6, 7] 构建右子树,然后将它们组合(即笛卡尔积)。

对于这个例子,不同二叉搜索树的个数为 F(3, 7)。我们将 [1,2] 构建不同左子树的数量表示为 G(2), 从 [4, 5, 6, 7] 构建不同右子树的数量表示为 G(4),注意到 G(n) 和序列的内容无关,只和序列的长度有关。于是,F(3,7)=G(2)⋅G(4)。 因此,我们可以得到以下公式:
F(i,n)=G(i−1)⋅G(n−i)F(i,n)=G(i−1)⋅G(n−i)F(i,n)=G(i−1)⋅G(n−i)将两个公式结合,可以得到 G(n) 的递归表达式:
G(n)=∑i=1nG(i−1)∗G(n−i)G(n)=\sum_{i=1}^{n}G(i-1)*G(n-i)G(n)=i=1∑n​G(i−1)∗G(n−i)至此,我们从小到大计算 G 函数即可,因为 G(n) 的值依赖于 G(0)⋯G(n−1)。

Code

    def numTrees(self, n: int) -> int:G = [0] * (n + 1)G[0], G[1] = 1, 1for i in range(2, n + 1):for j in range(1, i + 1):G[i] += G[j - 1] * G[i - j]return G[n]

复杂度分析

时间复杂度 : O(n2),其中 n 表示二叉搜索树的节点个数。G(n) 函数一共有 n 个值需要求解,每次求解需要 O(n) 的时间复杂度,因此总时间复杂度为 O(n2)。

空间复杂度 : O(n)。我们需要 O(n) 的空间存储 G 数组。

96. Unique Binary Search Trees 不同的二叉搜索树相关推荐

  1. LeetCode:96. Unique Binary Search Trees(找出独一无二搜索树)

    文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼:我热爱编程.热爱算法.热爱开源.所有源码在我的个人github :这博客是记录我学习的点点滴滴,如果您对 Python.Java.AI ...

  2. LeetCode 96. Unique Binary Search Trees

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

  3. 【卡塔兰数】LeetCode 96. Unique Binary Search Trees

    LeetCode 96. Unique Binary Search Trees 本博客转载自:http://www.cnblogs.com/grandyang/p/4299608.html Solut ...

  4. leetcode 95. Unique Binary Search Trees II | 96. Unique Binary Search Trees

    95. Unique Binary Search Trees II https://leetcode.com/problems/unique-binary-search-trees-ii/ 题解 题是 ...

  5. 96. Unique Binary Search Trees(I 和 II)

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

  6. [LeetCode]: 96: Unique Binary Search Trees

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

  7. [swift] LeetCode 96. Unique Binary Search Trees

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

  8. 96. Unique Binary Search Trees【力扣】

    题意理解 给定一个整数n,从1到n序列可组成多少个不同的二叉树? 问题分析 用动态规划 状态量是dp[i]表示i个整数可组成不同的二叉树的数量. 状态转移方程 dp[i] = sum(dp[j-1] ...

  9. Unique Binary Search Trees ll -深度优先遍历DFS

    题目:Unique Binary Search Trees ll English: Given an integer n, generate all structurally unique BST's ...

最新文章

  1. docker一步安装mysql,docker的魅力就在于此
  2. Linux实战教学笔记37:企业级Nginx Web服务优化实战(上)
  3. [剑指offer][JAVA]面试题第[11]题[旋转数组的最小数字][二分法][分治]
  4. 转载一篇短小精悍的博文:强可学习在什么条件下与弱可学习等价
  5. 京东扩招 1.5 万员工;程维卸任快的打车法人;库克纪念乔布斯 64 岁诞辰 | 极客头条...
  6. 吴恩达神经网络和深度学习-学习笔记-25-定位数据不匹配
  7. 实战中总结出来的CSS常见问题及解决办法
  8. Python爬虫教程-22-lxml-etree和xpath配合使用
  9. AI和数学领域的咖啡甜心(一):DeepFace基础
  10. 程序员,如何做好工作复盘?
  11. 【C++】C++入门
  12. 《很杂很杂的杂学知识》 学习笔记
  13. C语言算法题:一只小蜜蜂...
  14. 2018 Unite大会——《使用UPA工具优化项目》演讲实录
  15. 虚拟 DOM 是什么? 有什么优缺点?
  16. .c_str()函数解析
  17. ValueError: Unknown activation function: ReLU
  18. GOM传奇引擎登录器商业版与免费版的区别
  19. 和成熟男人谈恋爱是什么感觉
  20. 如何用邮件(微信)接收交易信号?

热门文章

  1. MVC 中 Razor 无限分类的展示
  2. 转载:Spring AOP (下)
  3. GridView的 使用
  4. scrum 12.2
  5. python朋友圈自动点赞_基于AirTest+Python的ios自动化测试demo(微信朋友圈无限点赞)...
  6. 求最大、次大和第3大的值
  7. python中的ideavim有什么作用_Pycharm和Idea支持的vim插件的方法
  8. Java黑皮书课后题第7章:*7.12(倒置数组)7.7节中的reverse方法通过复制到新数组实现倒置。改写方法将参数中传递的数组倒置,并返回该数组。编写一个测试程序,输入10个数字,倒置它们并显示
  9. Java黑皮书课后题第2章:*2.21(金融应用:计算未来投资回报)编写程序,读取投资总额、年利率和年龄,显示未来投资回报金额
  10. 随机变量的分布函数-定义域问题