Loading

[LeetCode] 96. Unique Binary Search Tree(互异的二叉搜索树)

Description

Given n, how many structurally unique BST's (binary search trees) that stores values 1 ... n?
给定一个整数 n,现有一棵二叉搜索树用以存储 1...n 之间的数,问有多少种不同的树结构?

Example

Input: 3
Output: 5
Explanation:
Given n = 3, there are a total of 5 unique BST's:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

Constraints

  • 1 <= n <= 19

Solution

这题一开始的时候找半天规律没找出来,翻了 discussion 才发现自己太连清了,没那种敏感度。

给定一个序列 1..n,构建二叉搜索树,可以理解成分别以 1, 2, 3, ..., n 作为 root 构建二叉搜索树,然后将这些结果求和得到。为了描述方便,定义以下两个函数:

  • \(G(n)\) :表示以 n 个节点构造二叉搜索树的数量(这也是题目要求求解的)

  • \(F(i, n)\):表示以 n 个节点,且以节点 \(i\)root 构造的二叉搜索树的数量

根据以上定义:我们可以对 \(G(n)\) 写出如下求解公式:

\[G(n) = \begin{cases} 1, &n = 0 或 1\\ \sum_{i = 1}^{n}{F(i, n)}, &else \end{cases} \]

那么该如何求解 \(F(i, n)\) 呢?我们不妨先试着求解一个具体的例子,比如求解 \(F(3, 7)\)。要从 [1, 2, 3, 4, 5, 6, 7] 序列中以 3root 构建 BST,那么根据 BST 的特性,其左子树一定是由 [1, 2] 构成的 BST,其右子树一定是 [4, 5, 6, 7] 构成的 BST,且左右子树的结构可以任意组合。那么以 [1, 2] 构成的 BST,其结构有多少种?\(G(2)\),以 [4, 5, 6, 7] 构建 BST,其结构有多少种?\(G(4)\)。于是得 \(F(3, 7) = G(2) \times G(4)\),推广到对任意 \((i, n)\),可得 \(F(i, n) = G(i - 1) \times G(n - i)\)。代入上面 \(G(n)\) 的表达式中,得:

\[G(n) = \begin{cases} 1, &n = 0 或 1\\ \sum_{i = 1}^{n}{G(i - 1) \times G(n - i)}, & else \end{cases} \]

上式即为所求的状态方程。不过我还是不能理解那个题解最后怎么把上式转成迭代的。所以我的解答里的动归采用的是带记忆的搜索形式,至少对于我来说比较容易理解,同时时间复杂度也不会很差。

class Solution {
    private val memo = hashMapOf<Int, Int>(
        0 to 1, 1 to 1
    )

    fun numTrees(n: Int): Int {
        if (memo.containsKey(n)) {
            return memo.getValue(n)
        }
        var sum = 0
        for (i in 1..n) {
            sum += numTrees(i - 1) * numTrees(n - i)
        }
        memo[n] = sum
        return sum
    }
}
posted @ 2020-11-09 09:50  Zhongju.copy()  阅读(52)  评论(0编辑  收藏  举报