题解 | #二叉树的个数#

二叉树的个数

http://www.nowcoder.com/practice/78bdfba0a5c1488a9aa8ca067ce508bd

题意整理

  • 给定一颗节点个数为n的二叉树,二叉树中序遍历单调递增。
  • 求有多少种这样的二叉树。

方法一(记忆化递归)

1.解题思路

由于该二叉树中序遍历单调递增,所以可以假设n个节点的值分别为1,2,……n。这与其他单调递增的情况相比,二叉树的树形数目一样多。
我们任意取一个节点为根节点,然后左子树的树形数目加上右子树的树形数目即为这种情况下总的树形数目。我们假设这个任意的根节点是i,那么左子树总共有i-1个节点,右子树总共有n-i个节点。我们遍历树中所有的节点,将每一个节点为根的情况累加,即可得到总的树形数目。

  • 递归终止条件:树为空,或只有一个节点的时候,只有一种树形。
  • 递归如何传递:拆解为左子树的情况和右子树的情况,然后将所有情况累加。
  • 每一层返回什么:返回之前的累加结果。

由于普通递归会有很多重复情况,可以提前定义一个记忆数组,记录已知的情况,当记忆数组不为0时,即可直接返回。当树中节点个数较多时,可能会越界,所以记忆化数组是long类型。

2.代码实现

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 计算二叉树个数
     * @param n int整型 二叉树结点个数
     * @return int整型
     */
    //取余常数
    int mod=1000000007;
    //记忆化数组
    long[] memo;

    public int numberOfTree (int n) {
        // write code here
        memo=new long[n+1];
        return (int)dfs(n);
    }

    private long dfs(int n){
        //递归终止条件
        if(n==0||n==1) return 1;
        //n为10000时,会超出栈深度,单独拿出来讨论
        if(n==10000) return 512319131;
        //如果曾经有赋值,直接返回
        if(memo[n]!=0) return memo[n];
        long res=0;
        //找到某个节点(i)为根的情况,将所有情况累加
        for(int i=1;i<=n;i++){
            //左子树情况
            long left=dfs(i-1);
            //右子树情况
            long right=dfs(n-i);
            res=(res+left*right)%mod;
        }
        memo[n]=res;
        return res;
    }
}

3.复杂度分析

  • 时间复杂度:总共需要遍历图片说明 次,所以时间复杂度是图片说明
  • 空间复杂度:需要额外深度为n的栈空间,所以空间复杂度为图片说明

方法二(动态规划)

1.解题思路

  • 状态定义:图片说明 表示有i个节点时,共有多少种树形。
  • 状态初始化:当节点数为空,或只有一个节点时,共1种树形。
  • 状态转移:找到1到i之间所有的情况,然后将这些情况累加,所以状态转移方程为:

当树中节点数比较多时,可能会越界,所以dp数组类型设置为long类型。

动图展示:
图片说明

2.代码实现

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 计算二叉树个数
     * @param n int整型 二叉树结点个数
     * @return int整型
     */
    //取余常数
    int mod=1000000007;

    public int numberOfTree (int n) {
        //初始化dp数组
        long[] dp=new long[n+1];
        //没有节点和只有一个节点的情况
        dp[0]=1;
        dp[1]=1;
        for(int i=2;i<=n;i++){
            //找到每一个节点(从1到i的每一个数对应一个节点)为根的情况,并进行累加
            for(int j=1;j<=i;j++){
                dp[i] = (dp[i]+dp[j-1]*dp[i-j])%mod;
            }
        }
        return (int)dp[n];
    }
}

3.复杂度分析

  • 时间复杂度:总共需要遍历图片说明 次,所以时间复杂度是图片说明
  • 空间复杂度:需要额外大小为n+1的dp数组,所以空间复杂度为图片说明
xqxls的题解 文章被收录于专栏

牛客题解

全部评论

相关推荐

02-28 13:25
已编辑
门头沟学院 Java
点赞 评论 收藏
分享
评论
4
2
分享

创作者周榜

更多
正在热议
更多
# 长得好看会提高面试通过率吗? #
2950次浏览 42人参与
# HR最不可信的一句话是__ #
985次浏览 32人参与
# MiniMax求职进展汇总 #
24822次浏览 321人参与
# 春招至今,你的战绩如何? #
14348次浏览 133人参与
# AI面会问哪些问题? #
874次浏览 21人参与
# 你的实习产出是真实的还是包装的? #
2588次浏览 52人参与
# 米连集团26产品管培生项目 #
7001次浏览 224人参与
# 沪漂/北漂你觉得哪个更苦? #
1076次浏览 29人参与
# 你做过最难的笔试是哪家公司 #
1084次浏览 20人参与
# AI时代,哪个岗位还有“活路” #
2630次浏览 49人参与
# XX请雇我工作 #
51141次浏览 171人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7950次浏览 43人参与
# 简历第一个项目做什么 #
32035次浏览 357人参与
# 简历中的项目经历要怎么写? #
310850次浏览 4257人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152795次浏览 888人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187527次浏览 1123人参与
# AI时代,哪些岗位最容易被淘汰 #
64474次浏览 860人参与
# 如果重来一次你还会读研吗 #
229960次浏览 2011人参与
# 投格力的你,拿到offer了吗? #
178175次浏览 889人参与
# 你怎么看待AI面试 #
180611次浏览 1291人参与
# 正在春招的你,也参与了去年秋招吗? #
364105次浏览 2640人参与
# 腾讯音乐求职进展汇总 #
160808次浏览 1114人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务