代码随想录算法训练营day16|二叉树最大深度、n叉树最大深度、二叉树最小深度、完全二叉树的节点个数

2023.3.30 二叉树的最大深度

104. 二叉树的最大深度 - 力扣(LeetCode)

方法一 递归法

思路:使用后序遍历的方法,先求左子树的最大深度,再求右子树的最大深度,那么总的最大深度一定是左右最大深度里面的更大的那一个再+1(计算上根节点)。

退出条件就是当前节点为null,返回高度0。

class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        int leftDepth = maxDepth(root.left);
        int rightDepth = maxDepth(root.right);
        return Math.max(leftDepth,rightDepth) + 1;
    }
}

方法二 BFS

class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        //广度优先遍历
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int depth = 0;
        while(!queue.isEmpty()){
            int length = queue.size();
            for(int i = 0;i<length;i++){
                TreeNode temp = queue.poll();
                if(temp.left != null) queue.offer(temp.left);
                if(temp.right != null) queue.offer(temp.right);
            }
            depth++;
        }
        return depth;
    }
}

2023.3.30 二叉树的最小深度

111. 二叉树的最小深度 - 力扣(LeetCode)

方法一 递归法

我们似乎很容易想到使用和求最大深度相反的思路,利用min来获取最小高度从而进行递归,然而这样的做法会有错误,因为当根节点只有一个子节点时,此时该做法会判断根节点有一个节点为空,直接返回最小值1,然而我们并不能这样判断。

错误代码:

class Solution {
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        int leftDepth = minDepth(root.left);
        int rightDepth = minDepth(root.right);
        return Math.min(leftDepth,rightDepth) + 1;
    }
}

因为我们需要判断的是叶子结点,而如果仅有一个左节点或者右节点为空,是不能构成最小深度的要求的,因此我们需要排除这两种情况。

class Solution {
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        //当左子节点为null而右子节点不为null,则还未到达叶子结点,继续进入右子节点判断
        if(root.left == null && root.right!=null){
            return minDepth(root.right) + 1;
        }
        if(root.left !=null && root.right == null){
            return minDepth(root.left) + 1;
        }
        int leftDepth = minDepth(root.left);
        int rightDepth = minDepth(root.right);
        return Math.min(leftDepth,rightDepth) + 1;
    }
}

方法二 BFS

逻辑很简单,我们只需要在判断二叉树最大深度的BFS代码中稍作修改即可,求最大深度我们需要一直将所有节点判断完,而求最小深度则不然,我们需要找到一个叶子结点,因此,需要在队列取出的节点中判断是否为叶子结点,如果是,则直接返回高度+1即可。

class Solution {
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        //广度优先遍历
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int depth = 0;
        while(!queue.isEmpty()){
            int length = queue.size();
            for(int i = 0;i<length;i++){
                TreeNode temp = queue.poll();
                if(temp.left != null) queue.offer(temp.left);
                if(temp.right != null) queue.offer(temp.right);
                if(temp.left == null && temp.right == null){
                    return depth + 1;
                }
            }
            depth++;
        }
        return depth;
    }
}

2023.3.30 完全二叉树的节点个数

222. 完全二叉树的节点个数 - 力扣(LeetCode)

总的节点个数等于根节点个数加上左子树节点个数加上右子树节点个数,而左子树节点个数又等于左子树根节加上其左子树节点个数和右子树节点个数,这是一个递归的过程,因此我们可以借鉴之前求最大深度的思路,使用递归完成。

方法一 后序遍历递归

class Solution {
    public int countNodes(TreeNode root) {
        if(root == null){
            return 0;
        }
        int leftNodes = countNodes(root.left);
        int rightNodes = countNodes(root.right);
        return leftNodes + rightNodes + 1;
    }
}

方法二 层序遍历记录每个节点

class Solution {
    public int countNodes(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        if(root == null){
            return 0;
        }
        queue.offer(root);
        int count = 0;
        while(!queue.isEmpty()){
            int length = queue.size();
            for(int i= 0;i<length;i++){
                TreeNode temp = queue.poll();
                count++;
                if(temp.left != null) queue.offer(temp.left);
                if(temp.right != null) queue.offer(temp.right);
            }
        }
        return count;
    }
}

2023.3.30 n叉树的最大深度

559. N 叉树的最大深度 - 力扣(LeetCode)

方法一 层序遍历

与普通的二叉树略有不同,由于一个节点可能有很多个子节点,所以这里我们需要使用循环来遍历子节点

class Solution {
    public int maxDepth(Node root) {
                if(root == null){
            return 0;
        }
        //广度优先遍历
        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);
        int depth = 0;
        while(!queue.isEmpty()){
            int length = queue.size();
            for(int i = 0;i<length;i++){
                Node temp = queue.poll();
                if(!temp.children.isEmpty()){
                    int cdLength = temp.children.size();
                    for(int j = 0;j<cdLength;j++){
                        queue.offer(temp.children.get(j));
                    }
                }
           
            }
            depth++;
        }
        return depth;
    }
}

方法二 递归法

同样的我们也可以使用递归来完成。

在二叉树中,我们要求根节点的最大深度,需要求根节点的左右子树里面的最大深度。

那么在多叉树中,我们要求根节点的最大深度,就需要求根节点的子节点里面的最大深度。

由于涉及到了多个节点,我们不能仅用两个重复调用方法得到子节点的最大深度,这里需要用到循环,去判断每一个子节点的最大深度。

class Solution {
    public int maxDepth(Node root) {
        if(root == null){
            return 0;
        }
        int depth = 0;
        for(Node temp : root.children){
            //记录子节点的最大深度
            depth = Math.max(depth,maxDepth(temp));
        }
        return depth + 1;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值