题目
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 1:
\
输入: n = 3
输出: 5
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
public int numTrees(int n) {
// g[i]表示长度为i,对应的二叉搜索树的不同数量
int[] g = new int[n + 1];
// 显然:当长度为0/1时对应的数量都是1
g[0] = 1;
g[1] = 1;
for (int i = 2; i <= n; i++) {
// 当长度为i时,可能以第一个元素到第i个元素都可能为顶点;所以把这些可能都加起来
for (int j = 1; j <= i; j++) {
// 当以j为顶点后,当前可能性就是j左边的二叉排序树数量*右边的数量(即组合)
g[i] += g[j - 1] * g[i - j];
}
}
return g[n];
}
解析
利用动态规划去做比较简单
核心点:int[] g = new int[n + 1];代表的含义;注意一定要以长度作为这个动态规划的子问题去做才比较简单;即g[i]代表长度为i的子串的二叉搜索树的数量
边界条件:g[0]==g[1]==1
递归表达式:g[i] = for(int j=1;j<=i;j++){g[i]+=g(j-1) is *g(i-j)} (即i长度上每个节点为顶点时的数量和)
总结
之前考虑用递归去做,大方向找错了;在递归时,确定子条件选择的是0->i -1 && i+1->n;即选择的是序列,而不是长度去做自问题解析,就会变得复杂
而这道题,是不需要关注当前序号的,只需要长度就可以确定子集,即官方答案