小白刷代码随想录day16--104.二叉树的最大深度 559.n叉树的最大深度,111.二叉树的最小深度,222.完全二叉树的节点个数

写在前面:递归--知道如何处理一个根节点就可以。“以一点处理万点”。这可能是我现在悟到的递归的真谛。(也就是递归三步曲的第三步:单层递归的逻辑)

104. 二叉树的最大深度 (优先掌握递归)

题目

104. 二叉树的最大深度

解题要点

视频:二叉树的高度和深度有啥区别?究竟用什么遍历顺序?很多录友搞不懂 | 104.二叉树的最大深度

文字版:代码随想录|二叉树的最大深度--递归法

后序遍历,根节点的高度即是二叉树的最大深度

(也可以用前序遍历,但后序遍历代码简单点)

代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        /**后序遍历(左右中) 根节点的高度即是二叉树的最大深度 */
        //确定参数和返回值
        //确定终止条件
        if(root == null) return 0;
        int leftheight = maxDepth(root.left); //左
        int rightheight = maxDepth(root.right); //右
        int height = 1 + Math.max(leftheight, rightheight); //中(左右孩子的最大高度+1返回给父节点)
        return height; 

    }
}

559. n叉树的最大深度

题目

559. N 叉树的最大深度

代码

这个是学会了上面二叉树的以后自己写出来的

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public int maxDepth(Node root) {
        /**N叉树的最大深度:后序遍历,根节点的高度就是最大深度 */
        //1. 确定递归的参数和返回值
        //2. 确定递归终止条件
        if(root == null) return 0;

        //3. 确定单层递归逻辑
        int maxheight = 0; //用来存储子节点的最高高度
        for(Node child : root.children){
            int childheight = maxDepth(child); //每一个子节点的高度
            maxheight = Math.max(maxheight, childheight); 
        }
        int height = 1 + maxheight;
        return height;
        
    }
}

111. 二叉树的最小深度(优先掌握递归)

题目

111. 二叉树的最小深度

解题要点

注意左/右子树其中一个为null另一个不为null的情况,不处理这种情况会返回错误的最小深度。

具体看视频和文字讲解:代码随想录|111.二叉树的最小深度

代码

class Solution {
    public int minDepth(TreeNode root) {
        /**后序遍历,用高度计算深度,递归 */
        //1. 确定递归的参数和返回值
        //2. 确定递归终止条件
        if(root == null) return 0;

        //3.确定单层递归逻辑
        int left_minheight = minDepth(root.left); //左
        int right_minheight = minDepth(root.right); //右

        //中
        //int height = Math.min(left_minheight, right_minheight); 
        //直接取最小值的话未考虑一种情况,就是当前root左/右子树为空时,返回的最小深度不是叶子节点的最小深度而是当前root的深度1.如示例2.
        //当左子树为空而右子树不为空时,返回右子树的最小高度+1
        if(root.left == null && root.right != null){
            return 1 + right_minheight;
        }
        //当右子树为空而左子树不为空时,返回左子树的最小高度+1
        if(root.left != null && root.right == null){
            return 1 + left_minheight;
        }
        //当左右子树都为空或都不为空时,返回左右子树的最小高度的最小值+1(都为空时返回1+ min(0,0))
        return 1 + Math.min(left_minheight, right_minheight);


    }
}

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

题目

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

解题要点

可以用普通二叉树去后序遍历返回节点数。但这里是完全二叉树,借助完全二叉树的特性去做性能更优,可以不必像普通二叉树方法那样遍历全部的节点。

完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。

对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。

对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。

判断其子树是不是满二叉树,如果是则利用公式计算这个子树(满二叉树)的节点数量,如果不是则继续递归。

因此本题终止条件比一般的后序遍历要多一个:判断子树是否为满二叉树。当子树为满二叉树时,递归终止,返回子树满二叉树的节点数。

视频和文字讲解详见:

代码随想录|222.完全二叉树的节点个数

代码

class Solution {
    public int countNodes(TreeNode root) {
        /**利用完全二叉特性 */
        /**除底层外, 其他层都是满的。底层从左到右连续*/
        /**一定能遍历到左子树是满二叉树,右子树是满二叉树,满二叉树节点数2^k -1, num = 左子满二叉树num + 右子满二叉树num + 1 */
        
        /**后序遍历,递归 */
        //1.确定递归的返回值和参数
        //2.确定递归终止条件
        //终止条件1:当节点为null时
        if(root == null) return 0;
        //终止条件2: 判断子树是否为满二叉树
        TreeNode left = root.left;
        TreeNode right = root.right;
        int leftdepth = 0; int rightdepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
        while(left != null){
            left = left.left;
            leftdepth ++;
        }
        while(right != null){
            right = right.right;
            rightdepth ++;
        }
        if(leftdepth == rightdepth){
            return (2 << leftdepth) - 1; //(左移)位运算,2的深度次方-1
            //树的深度k从1开始,而这里leftdepth从0开始,但是位运算 2<<1 = 2^2, 2<<0 = 2^1,因此正好是2<<(leftdepth) -1
            //位运算 要用括号括起来
        }
        //3.确定单层递归逻辑
        int leftNotes = countNodes(root.left); //左 (不能直接用left,left变了)
        int rightNotes = countNodes(root.right); //右
        int result = leftNotes + rightNotes + 1; //中
        return result;

    }
}

注:这里有个位运算。关于位运算的知识可以参考Java 位运算(移位、位与、或、异或、非)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值