一、问题描述:给你一个整数 n
,求恰由 n
个节点组成且节点值从 1
到 n
互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
输入: n=2
输出:5
示例2:
输入:n=1
输出:1
二、问题分析
先写几个例子,找一下规律
- f[0]=1
- f[1]=1
- f[2]=2
- f[3]=5
- f[4]=14
当我把这几个列出来的时候,我并没有找到神魔有用的规律。但是,我知道这道题要用的是动态规划,那就肯定嘚找状态方程 。最终问题,肯定和子问题有关系。
那么,当i=4时,有四个节点[1,2,3,4]这四个节点中,每一个都可能是根节点,当1是根节点时,那它左侧为0个节点构成的二叉搜索树,右侧为3个节点构成的二叉搜索树。即:当1是根节点时,共有 f[0]*f[3]种结果,依次类推,当2是根节点时,共有f[1]*f[2]。当3是根节点时呢?这个情况和2为根节点一样,当4是根节点时,结果和1是根节点结果一样。
在计算每一种结果的时候,都会出现重复的情况。所以:
这里x2就是为了不再计算重复的,如果是奇数就要加上f[i/2]*f[i/2](也就是我上面写的f[target-1]*target[i-1])
三、代码实现
public static int numTrees(int n) {
if (n==0 || n==1)return 1;
int[] f=new int[n+1];
f[0]=1;
f[1]=1;
int target=0;
int k=0;
int sum=0;
for (int i = 2; i < n + 1; i++) {
target=i%2==0?i/2:i/2+1;
for (int j = i-1; j >=target ; j--) {
k=i-j-1;
sum+=f[k]*f[j];
}
sum*=2;
if (i%2!=0){
sum+=f[target-1]*f[target-1];
}
f[i]=sum;
sum=0;
}
return f[n];
}