LeetCode 96 不同的二叉搜索树

分析

1)用升序序列1…n构建一棵二叉搜索树,根节点任选一个,有n种选法。
2)但是选定了一个数作为根节点i(i∈[1,n]),那么由于二叉搜索树的特性,左子树只能用1…i-1构建,右子树只能用i+1…n构建。
3)设用1…i-1构建左子树有x种方法,用i+1…n构建右子树有y种方法,那么以i为根的二叉搜索树共x×y种。
4)把i依次取1,2,3…n的所得的结果累加起来便是最终结果。
需要注意的是,用元素个数相同的升序序列构造出的二叉搜索树的种类是相同的。比如用1,2,3构造出的二叉搜索树种数和用4,5,6构造出来的种数相同,因此我们只关心这个序列的个数,而不用关心它的大小。
递归的出口是,根节点是n=0或n=1

class Solution {
    public int numTrees(int n) {
        if (n == 0 || n == 1) {
            return 1;
        }
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            ans += numTrees(i - 1) * numTrees(n - i);
        }
        return ans;
    }
}

注意上面的代码虽然可以通过,但是运行的额速度很慢,这是因为时间复杂度太高是指数级别,因为存在很多重复计算,比如说numTrees(2)会计算很多次。如果把递归函数修改成下面这样的,时间复杂度就会变低。

class Solution {
    public int numTrees(int n) {
        int[] record = new int[n + 1];  //空间换时间的思想
        record[0] = 1;  
        return helper(n, record);
    }

    public int helper(int n, int[] record) {
        if (n == 0 || n == 1) {     // 递归出口
            return 1;
        }
        if (record[n] > 0) {        // 如果计算过了
            return record[n];       // 提前返回结束递归求解,省时省空间
        }
        for (int i = 1; i <= n; i++) {
            record[n] += helper(i - 1, record) * helper(n - i, record);
        }
        return record[n];   
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值