题目:
96、不同的二叉搜索树
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
题解思路:
1、思路
如果整数 1 ~ n 中的 k 作为根节点值,则 1 ~ k-1 会去构建左子树,k+1 ~ n 会去构建右子树。
左子树出来的形态有 a 种,右子树出来的形态有 b 种,则整个树的形态有 a∗b 种。
以 k 为根节点的 BST 种类数 = 左子树 BST 种类数 * 右子树 BSTBST 种类数。
问题变成:不同的 kk 之下,等号右边的乘积,进行累加。
2、定义 DP 子问题
(1)用 2、3 构建,和用 1、2 构建,出来的种类数是一样的,因为参与构建的个数一样。
(2)再比如 2,3,4 和 1,2,3 都是连着的三个数,构建出的 BST 的种类数相同,属于重复的子问题。
(3)定义 dp[i]:用连着的 i 个数,所构建出的 BST 种类数。
3、状态转移方程:
用 i 个节点构建 BST,除去根节点,剩 i-1 个节点构建左、右子树,左子树分配 0 个,则右子树分配到 i−1 个……以此类推。
左子树用掉 j 个,则右子树用掉 i-j-1 个,能构建出 dp[j] * dp[i-j-1] 种不同的BST。
4、基础条件
当 n = 0 时,没有数字,只能形成一种 BST :空树。
当 n = 1 时,只有一个数字,只能形成一种 BST :单个节点。
时间复杂度 O(n^2):有 n 个状态需要计算,计算每个状态又需要 O(n)。
题解python代码:
class Solution:
def numTrees(self, n: int) -> int:
G = [0]*(n+1)
G[0], G[1] = 1, 1
for i in range(2, n+1):
for j in range(i):
G[i] += G[j] * G[i-j-1]
return G[n]
作者:xiao_ben_zhu
链接:https://leetcode-cn.com/problems/unique-binary-search-trees/solution/shou-hua-tu-jie-san-chong-xie-fa-dp-di-gui-ji-yi-h/
来源:力扣(LeetCode)https://leetcode-cn.com/problems/unique-binary-search-trees/