1. question: 不同的二叉搜索树(中等)
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/unique-binary-search-trees
示例 1:
1 | 输入:n = 3 |
示例 2:
1 | 输入:n = 1 |
提示:
1 | 1 <= n <= 19 |
2. answers
这道题没想出来,参考了题解。主要有一下几个要点:
求解整数n的所有二叉搜索树,那么[1,n]之间每一个数都可作为根节点出现。
比如数字x,那么[1,x]只能作为左子树出现,[x,n]只能作为右子树。
显然,x作为根节点形成的二叉搜索树的数量 = [1,x]形成的二叉搜索树数量 * [x,n]形成的二叉搜索树数量。
那么n所有的二叉搜索树,就是[1,n]各个数形成的二叉搜索树数量之和,每个数都可由第3点求解。
[1,x]形成的二叉搜索树,其实就回归到本题了。
[x,n]形成的二叉搜索树,该怎么求解呢?因为题目求解的是数量,显然对于数值没有太大的要求。对于[x,n]形成的二叉搜索树,其实和[1, n-x]形成二叉搜索树是一样的,因为元素的相对大小都是完全匹配的。
比如[1,2,3,4]和[5,6,7,8]四个数,其实形成的二叉搜索树是一样的。
此时,n形成的二叉搜索树,可由[1,x]和[1,n-x]求的。而x则是[1,n]之间的任意数。
由此可得递推公式:dp[n] = (dp[0] * dp[n-1]) + (dp[1] * dp[n-2]) + (dp[2] * dp[n-3]) + … + (dp[n-1] * dp[0])
注意,因为根节点占用了一个数,所以左右子树节点之和为n-1。
设dp[x]表示[1,x]所形成的所有二叉搜索树总数。
另外,左子树为空,显然本数的二叉搜索树总数取决于右子树,即dp[0]为1。代码如下所示:
1 | public class Solution_0117 { |
其实对于dp[2],也可以不初始化。代码如下所示:
1 | public int numTrees(int n) { |
3. 备注
参考力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 (leetcode-cn.com),代码随想录 (programmercarl.com)。