Skip to main content

96.不同的二叉搜索树

标签: dynamic-programming, tree

难度: Medium

通过率: 61.89%

原题链接: https://leetcode.com/problems/unique-binary-search-trees/description/

题目描述

给定一个整数 nn,返回具有 nn 个节点的唯一值二叉搜索树的数量,这些节点的值从 1 到 nn

解题思路

要解决这个问题,我们可以使用动态规划。设 G(n)G(n) 表示有 nn 个不同节点可以组成的不同二叉搜索树的数量。我们尝试把每一个节点作为根节点,假设我们选择 ii 作为根节点:

  • 左子树的节点来自 11i1i-1,即有 i1i-1 个节点。
  • 右子树的节点来自 i+1i+1nn,即有 nin-i 个节点。

因此, G(i1) 是 i1 个节点组成的二叉搜索树的个数G(i-1) \text{ 是 } i-1 \text{ 个节点组成的二叉搜索树的个数} G(ni) 是 ni 个节点组成的二叉搜索树的个数G(n-i) \text{ 是 } n-i \text{ 个节点组成的二叉搜索树的个数}

所以,对于固定的根 ii,能够组成的二叉搜索树的数量为 G(i1)×G(ni)G(i-1) \times G(n-i)

通过对所有的可能根节点求和,有: G(n)=i=1nG(i1)×G(ni)G(n) = \sum_{i=1}^{n} G(i-1) \times G(n-i)

而边界条件是 G(0)=1G(0)=1,因为空树也是一种二叉搜索树。

因此,利用上述公式,我们可以从 G(0)G(0) 开始递归计算直到 G(n)G(n)

代码实现

def numTrees(n):
# 创建一个数组来存储所有 G(i) 的值
G = [0] * (n + 1)
# 边界条件
G[0], G[1] = 1, 1
# 从 2 到 n 开始动态规划计算
for 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)O(n^2),因为有两个嵌套的循环,每个循环迭代 nn 次。` 空间复杂度:O(n)O(n),因为我们使用了一个大小为 n+1n+1 的数组。