2020年7月15日 不同的二叉搜索树 numTrees
默认格式:
class Solution {
public int numTrees(int n) {
}
}
解题思路:
这道题我觉得应该是可以找到规律的,可以直接通过公式来计算种类数。
。。。
找不出规律,所以还是老老实实想解题的方法吧。
首先需要注意的一点,这道题说的是一个搜索树,搜索树的特点就是,父节点的左子树都比父节点小,父节点的右子树都比父节点大。
递归:
一个连续n个的连续整数,求搜索树种类数,那么就相当于求以1、2、3…为根节点时的搜索树的种类和。
当以1位根节点时,就相当于求2,3,4…组成的搜索树的种类数。
因为2,3,4…都在1的右边。
到这里,发现从多到少的递归不如从少到多地递归。
我们先计算4个连续数时有多少种类。
当1为根节点时,左边0个数,右边3个数,左边种类0,右边种类5,合计5种
当2为根节点时,左边1个数,右边2个数,左边种类1,右边种类2,合计2种
当3为根节点时,左边2个数,右边1个数,左边种类2,右边种类1,合计2种
当4位根节点时,左边3个数,右边0个数,左边种类5,右边种类0,合计5种
4种根节点都判断结束,合计14种。
然后我们计算5个连续数时有多少种类:
当1为根节点时,左边0个数,右边4个数,左边种类0,右边种类14,合计14种
当2为根节点时,左边1个数,右边3个数,左边种类1,右边种类5,合计5种
当3为根节点时,左边2个数,右边2个数,左边种类2,右边种类2,合计4种
当4位根节点时,左边3个数,右边1个数,左边种类5,右边种类1,合计5种
当4位根节点时,左边4个数,右边0个数,左边种类14,右边种类0,合计14种
合计42种
可以找到规律
f(n)=f(n-1)*2+f(n-2)*f(1)*2+f(n-3)*f(2)*2…f(n-a)*f(a-1)*2直到n-a<a-1
奇数和偶数有一些细微的区别。
如果使用递归的话会非常复杂,我们在向上递归的时候记录下f(n)的值,然后直接去数组中去取。这样可以省去重复的递归工作。或者说直接使用迭代。
代码实现:
public int numTrees(int n) {
ArrayList<Integer> array=new ArrayList<>(n+1);
array.add(0);
array.add(1);
for (int i=2;i<=n;i++){
int now=array.get(i-1)*2;
int j=2;
for (;i-j>j-1;j++){
now+=array.get(i-j)*array.get(j-1)*2;
}
if (i-j==j-1)
now+=array.get(i-j)*array.get(j-1);
array.add(now);
}
return array.get(n);
}