LeetCode 打卡day16 --完全二叉树的节点个数,树的最小深度


知识总结

今天接着继续二叉树. 一定要审题, 最后一道完全二叉树的节点个数完全看错了题目.

学会一种表达, 我们用位移运算来代替幂运算

2 << 1 等价于 2 ^ 2 = 4


Leetcode 104. 二叉树的最大深度

题目链接

题目说明

给定一个二叉树,找出其最大深度。

代码说明

class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null) return 0;

        return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;    
    }
}

Leetcode 559. N 叉树的最大深度

题目链接

题目说明

给定一个 N 叉树,找到其最大深度。

最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

代码说明

用递归和迭代都写了一下, 发现有时候递归反而更难想到. 其实思路和上面的题目一模一样. 确定终止条件, 然后确定循环条件.

递归法

class Solution {
    public int maxDepth(Node root) {
        if (root == null) return 0;
        int maxDepth = 0;
        for(Node child : root.children){
            maxDepth = Math.max(maxDepth(child), maxDepth);
        }
        return maxDepth + 1;
    }
}

迭代法

class Solution {
    public int maxDepth(Node root) {
        if (root == null) return 0;
        int maxDepth = 0;

        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            int len = queue.size();
            while(len > 0){
                Node cur = queue.poll();
                for(Node child : cur.children){
                    if(child != null){
                        queue.offer(child);
                    }
                }
                len--;
            }
            maxDepth++;
        }
        return maxDepth;
    }
}

Leetcode 111. 二叉树的最小深度

题目链接

题目说明

给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

代码说明

这样要注意, 叶子节点的定义, 不是遇到null就代表该节点是叶子节点. 需要递归时好好判断.

迭代法
这个思路反而更加清晰, 一层一层遍历, 遇到的第一个叶子节点就直接返回. 此时该节点的深度一定是最小的

class Solution {
    public int minDepth(TreeNode root) {
        if(root == null) return 0;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int deepth = 0;
        while(!queue.isEmpty()){
            int len = queue.size();
            while(len> 0){
                TreeNode cur = queue.poll();
                if(cur.left == null && cur.right == null){
                    return deepth + 1;
                }
                if(cur.left != null) queue.offer(cur.left);
                if(cur.right != null) queue.offer(cur.right);
                len--;
            }
            deepth++;
        }
        return deepth; 
    } 
}

递归法

需要分类讨论左子树和右子树是否为空的情况

class Solution {
    public int minDepth(TreeNode root) {
        if(root == null) return 0;

        if(root.left == null && root.right == null){
            return 1;
        }
        int m1 = minDepth(root.left);
        int m2 = minDepth(root.right);
		// 有一方为空, 为空的的深度就是0, 所以可以直接相加
        if(root.left== null || root.right == null){
            return m1 + m2 + 1;
        }
        // 左右都不为空, 则取最小值 + 1
        return Math.min(m1, m2) + 1;

    }
}

Leetcode 222. 完全二叉树的节点个数

题目链接

题目说明

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1   2 h 1~ 2^h 1 2h 个节点。

代码说明

题目已知的条件是给了一个完全的二叉树, 让我们去求树的节点个数. 正常的可以使用通用的遍历直接求.

但是这里我们做了一个优化.
如果我们发现给树一直到左和一直到右的深度相同, 则该子树为一个满二叉树, 满二叉树的节点数量公式为

n u m = 2 d e p t h − 1 num = 2 ^ {depth} -1 num=2depth1

这样可以减少遍历的次数

class Solution {
    public int countNodes(TreeNode root) {
       if(root == null) return 0;
       int leftDepth= 0, rightDepth = 0;
       TreeNode l = root.left;
       TreeNode r = root.right;

       while(l != null){
           l = l.left;
           leftDepth++;
       }

       while(r != null){
           r = r.right;
           rightDepth++;
       }

       if(leftDepth == rightDepth){
           return (2 << leftDepth) - 1;
       }
       return countNodes(root.left) + countNodes(root.right) + 1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值