[LeetCode] 96. Unique Binary Search Tree(互异的二叉搜索树)
-
Difficulty: Medium
-
Related Topics: Dynamic Programming, Tree
-
Link: https://leetcode.com/problems/unique-binary-search-trees/
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)\) 写出如下求解公式:
那么该如何求解 \(F(i, n)\) 呢?我们不妨先试着求解一个具体的例子,比如求解 \(F(3, 7)\)。要从 [1, 2, 3, 4, 5, 6, 7]
序列中以 3
为 root
构建 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)\) 的表达式中,得:
上式即为所求的状态方程。不过我还是不能理解那个题解最后怎么把上式转成迭代的。所以我的解答里的动归采用的是带记忆的搜索形式,至少对于我来说比较容易理解,同时时间复杂度也不会很差。
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
}
}