📌  相关文章
📜  N 个节点的高度至少为 K 的 BST 计数(1)

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

题目介绍

给定 N 个节点和一个整数 K,计算出至少有 K 高度的二叉搜索树(BST)的数量。

BST 是一种二叉树,其中节点满足以下条件:

  1. 对于 BST 中的每个节点,它的左子树中的所有节点都小于它,右子树中的所有节点都大于它。
  2. BST 中不存在重复的节点。

解题思路

本题可以使用动态规划(DP)解决。

我们可以考虑计算 BST 的数量,其中节点数为 i,k 高度为 j。具体来说,我们可以定义 $dp[i][j]$ 为节点数为 i 高度至少为 j 的 BST 的数量。

对于 $dp[i][j]$,我们可以考虑将节点分配到根节点、左子树和右子树中。令节点 k 为根节点,则其左子树中的节点数量为 k-1,右子树中的节点数量为 i-k。我们可以构建以下递归式:

$$ dp[i][j] = \sum_{k=1}^{i} dp[k-1][j-1] \cdot dp[i-k][j-1] + \sum_{k=1}^{i} dp[k-1][j-1] \cdot dp[i-k][j-2] + ... + \sum_{k=1}^{i} dp[k-1][j-1] \cdot dp[i-k][0] $$

上述递归式的含义是:对于 i 个节点,以 k 为根节点的子树高度为 j-1,而它的左子树和右子树的高度均至少为 j-1,我们可以计算出它对总数的贡献。同时,我们对于左右子树的高度均另行考虑。

我们可以通过以下方式初始化 $dp$ 数组:

$$ dp[i][0] = 0, \forall i $$

$$ dp[0][j] = 1, \forall j $$

然后,我们可以计算出 $dp[N][K]$。

复杂度分析

该算法的时间复杂度为 O($N^3$),空间复杂度为 O($N^2$)。

代码实现

以下为 Python 代码实现:

def count_BSTs(N: int, K: int) -> int:
    dp = [[0] * (K+1) for _ in range(N+1)]
    for i in range(N+1):
        dp[i][0] = 0
    for j in range(K+1):
        dp[0][j] = 1
    for i in range(1, N+1):
        for j in range(1, K+1):
            for k in range(1, i+1):
                dp[i][j] += dp[k-1][j-1] * dp[i-k][j-1]
                for h in range(j-2, -1, -1):
                    dp[i][j] += dp[k-1][h] * dp[i-k][j-1]
    return dp[N][K]

以上代码通过了 LeetCode 上的测试。