题目链接
思路:
不同的二叉搜索树的种类的计算方法:对于1~n中的一个数字 i,它作为根节点时,i-1全部为 i 的左子树,n - i 全部为 i 的右子树,那么以 i 为根节点时,不同的搜索二叉树的种类为 左子树的不同种类 * 右子树的不同种类
即:f(i) = f(i - 1) * f(n - i)
那么就可以写出下面的代码:
但是会超时,时间复杂度过高
public int numTrees(int start, int end) {
if (start > end) {
return 1;
}
int result = 0;
for (int i = start; i <= end; i++) {
result += numTrees(start, i - 1) * numTrees(i + 1, end);
}
return result;
}
每一次计算相同值的时候都需要重新计算,计算的结果没有进行保存,
例如:f(2) = f(2-1)*f(n-2)=f(1)*f(n-2),f(n-1)=f(n-1-1)*f(n-(n-1)) = f(n-2)*f(1)
这样就导致了重复计算了f(1)和f(n-2)
可以使用一个数组来保存每次计算的结果,之后就可以进行重复利用
public int numTrees(int n) {
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
return dp[n];
}