不同的二叉搜索树题目的思路探讨与源码
不同的二叉搜索树的题目如下图,该题属于树结构和动态规划类型的题目,主要考察对于树本身结构的理解和认识,结合树的左右子树进行思考就可以进行求解。本文的题目作者想到2种方法,第一种方法是动态规划方法,第二种方法是公式方法。其中第一种方法使用java写、第二种方法使用Python写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用动态规划和公式递归的方法,首先来说动态规划方法。我们观察初始情况,当树的节点是0或者1的时候,只有一种二叉搜索树的情况。而当一般情况的时候,我们可以用一个列表来描述这种情况,给定长度为n的列表,其中数值就是1、2、3…n,当我们访问列表的某个数值,数值左边和右边其实就是看作左子树和右子树,而这时候二叉搜索树的数量就是左右结果的笛卡尔积;所以我们最后只需要访问每个元素并且计算每个元素对应的二叉搜索树数量,最后进行求和就可以了。所以按照这个思路我们的代码如下:
#喷火龙与水箭龟
class Solution {
public int numTrees(int n) {
int[] tree = new int[n + 1];
tree[0] = 1;
tree[1] = 1;
for(int ir=2;ir<=n;ir++) {
for(int jr=1;jr<=ir;jr++) {
tree[ir]=tree[ir]+tree[jr-1]*tree[ir-jr];
}
}
return tree[n];
}
}
显然,还可以使用公式的方法来进行解决,该公式就是数论上比较有名的卡塔兰数。所以根据这个公式就可以写出代码,下面是Python代码部分:
#喷火龙与水箭龟
class Solution:
def numTrees(self, n: int) -> int:
N=1
for ir in range(0, n):
N=N*2*(2*ir+1)/(ir+2)
res=int(N)
return res
从结果来说java版本的动态规划还不错,但python版本的公式方法速度一般,因为其实公式法是类似递归的处理 ,但有可能是可以进一步提速的,希望朋友们能够多多指教,非常感谢。