leetcode-96
96. 不同的二叉搜索树
给你一个整数 n
,求恰由 n
个节点组成且节点值从 1
到 n
互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 1:
背景知识
二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树。是数据结构中的一类。在一般情况下,查询效率比链表结构要高。定义如下:
一棵空树,或者是具有下列性质的二叉树:
官方题解(动态规划)
给定一个有序序列$1 \cdots n1⋯n$,为了构建出一棵二叉搜索树,我们可以遍历每个数字$i$,将该数字作为树根,将 $1 \cdots (i-1)$ 序列作为左子树,将 $(i+1) \cdots n$ 序列作为右子树。接着我们可以按照同样的方式递归构建左子树和右子树。
在上述构建的过程中,由于根的值不同,因此我们能保证每棵二叉搜索树是唯一的。
由此可见,原问题可以分解成规模较小的两个子问题,且子问题的解可以复用。因此,我们可以想到使用动态规划来求解本题。
在上述构建的过程中,由于根的值不同,因此我们能保证每棵二叉搜索树是唯一的。
由此可见,原问题可以分解成规模较小的两个子问题,且子问题的解可以复用。因此,我们可以想到使用动态规划来求解本题。
算法
题目要求是计算不同二叉搜索树的个数。为此,我们可以定义两个函数:
- $G(n)$:长度为 $n$ 的序列能构成的不同二叉搜索树的个数。
- $F(i,n)$:以$i$为根、序列长度为$n$的不同二叉搜索树个数$ (1 \leq i \leq n)$。
$G(n)$是需要求解的函数。
根据上一节中的思路,不同的二叉搜索树的总数$G(n)$,是对遍历所有$i(i\leq i\leq n)$的$F(i,n)$之和。既:
$$
G ( n ) = \sum _ { i = 1 } ^ { n } F ( i , n ) \tag{1}
$$
对于边界情况,当序列长度为 1(只有根)或为 0(空树)时,只有一种情况,即:
$$
G ( 0 ) = 1 , \quad G ( 1 ) = 1
$$
给定序列 $1 \cdots 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)\cdot G(4)$。故可以得到以下公式:
$$
F ( i , n ) = G ( i - 1 ) \cdot G ( n - i ) \tag{2}
$$
结合式(1)(2),可以得到$G(n)$的表达式:
$$
G ( n ) = \sum _ { i = 1 } ^ { n } G ( i - 1 ) \cdot G ( n - i ) \tag{3}
$$
至此,我们从小到大计算$G$函数即可,因为$G(n)$的值依赖于$G(0),\dots,G(n-1)$。
1 | class Solution: |
leetcode-96