📜  给定密钥的唯一BST的数量|动态编程(1)

📅  最后修改于: 2023-12-03 15:11:39.979000             🧑  作者: Mango

给定密钥的唯一BST的数量

介绍

给定一个数值n,我们可以从1到n选定数值作为二叉查找树(BST)的节点。如果选择的根节点为i,则其左子树包含1到i-1这些数,而右子树包含i+1到n这些数。我们可以递归地构建BST,可以得到所有的BST的数量。

例如: n = 3 我们可以选择的数值:{1, 2, 3} 构建出的所有BST:{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {3, 1, 2}, {3, 2, 1} 共有5个BST。

动态编程

这个问题可以使用动态编程来解决。我们定义一个数组dp,其中dp[i]表示以i作为根节点的BST数量。

首先考虑最简单的情况n=0或n=1。这时只有一种情况,即空树或只有根节点的单一BST。所以我们可以将dp[0]和dp[1]初始化为1。

对于其他情况n>=2,我们从1到n枚举每一个节点i,将i作为根节点时,我们可以得到以下公式:

$$\text{dp}[n] = \sum_{i=1}^n \text{dp}[i-1] \times \text{dp}[n-i]$$

这个公式的意思是,以i为根节点的BST数量,等于其左子树BST的数量乘以右子树BST的数量,因为每一个左子树和右子树的组合都可以得到一个唯一的BST。

代码实现

以下是Python实现该算法的代码片段:

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

该实现的时间复杂度为$O(n^2)$,空间复杂度为$O(n)$。