代码随想录刷题——二叉树day16

87 阅读4分钟

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

这道题与上一篇文章中的102.层序遍历相同。

只不过102这道题目的要求是存储二叉树中的每一层的节点,而此题是计算二叉树的最大深度。

代码如下:


    /**
     * 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;
            Queue<TreeNode> queue=new LinkedList<>();
            //因为此时根节点不为空,所以depth初始化为1
            int depth=0;
            queue.offer(root);
            while(!queue.isEmpty()){
                //每次进入外层循环,层数+1
                depth++;
                //获取当前队列的元素个数
                int len=queue.size();
                while(len>0){
                    //内层循环做两件事
                    //1、排空队列中当前层数的所有节点
                    //2、依据层序遍历,将下一层节点加入到队列中
                    TreeNode curNode=queue.poll();
                    if(curNode.left!=null)
                        queue.offer(curNode.left);
                    if(curNode.right!=null)
                        queue.offer(curNode.right);
                    len--;
                }
            }
            return depth;
        }
    }

递归方法

  • 针对二叉树的题目,刷了这么些题,如果在最初始时考虑使用递归——那么在递归的细节当中要不然考虑二叉树的前序遍历、要不然考虑二叉树的后序遍历

  • 关于二叉树的深度以及高度的概念。

    • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
    • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)

递归方法1:使用二叉树的后序遍历——通过二叉树的高度来算深度

再次重复递归三要素:

  1. 递归函数的返回值是什么?形参是什么?

  2. 递归函数内部在什么时候return

  3. 每一轮递归,其细节处理是什么

一旦上面递归三要素确定了,之后就只需要考虑递归的调用顺序。

class Solution {
        public int maxDepth(TreeNode root) {
            return CalcDepth(root);
        }
        public int CalcDepth(TreeNode node){
            if(node==null){
                return 0;
            }
            //计算其左子树的高度
            int leftDepth=CalcDepth(node.left);
            //计算其右子树的高度
            int rightDepth=CalcDepth(node.right);
            int depth=Math.max(leftDepth,rightDepth)+1;
            return depth;
        }
    }

ad1ce8f9-bb33-4cf1-bd55-82160975547b.png

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

    class Solution {
        //还是考虑迭代法层序遍历
        //基本思路是遍历每一层的时候,只要当前层数有叶子节点,那么就可以直接return了;此时就没有必要再继续遍历下去
        public int minDepth(TreeNode root) {
            if(root==null)
                return 0;
            Queue<TreeNode> queue=new LinkedList<>();
            int minDepth=0;
            queue.offer(root);
            while(!queue.isEmpty()){
                minDepth++;
                int len=queue.size();
                while(len>0){
                    TreeNode node=queue.poll();
                    len--;
                    if(node.left!=null)
                        queue.offer(node.left);
                    if(node.right!=null)
                        queue.offer(node.right);
                   if(node.left==null && node.right==null)
                        return minDepth;
                }
            }
            return minDepth;
        }
    }

使用递归的方法来完成求解

使用后序遍历——左右中,但是这里与二叉树的最大深度不同的地方在于:最小深度 是根节点到最近叶子节点的最短路径上的节点数量。

Snipaste_2024-03-07_14-56-28.png

所以,如果左子树为空,右子树不为空,说明最小深度是 1 + 右子树的深度。

反之,右子树为空,左子树不为空,最小深度是 1 + 左子树的深度。 最后如果左右子树都不为空,返回左右子树深度最小值 + 1 。

class Solution {
        /**
         * 递归法,相比求MaxDepth要复杂点
         * 因为最小深度是从根节点到最近**叶子节点**的最短路径上的节点数量
         */
        public int minDepth(TreeNode root) {
            if (root == null) {
                return 0;
            }
            int leftDepth = minDepth(root.left);
            int rightDepth = minDepth(root.right);
            if (root.left == null) {
                return rightDepth + 1;
            }
            if (root.right == null) {
                return leftDepth + 1;
            }
            // 左右结点都不为null
            return Math.min(leftDepth, rightDepth) + 1;
        }
    }

222.完全二叉树的节点个数(优先掌握递归)


    /**
     * 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 {
        //考虑使用迭代的方法前序遍历二叉树,来完成节点个数的统计
        int nodeNum=0;
        public int countNodes(TreeNode root) {
            if(root==null)
                return 0;
            preOrder(root);
            return nodeNum;
        }
        public void preOrder(TreeNode node){
            //前序遍历顺序————中左右
            if(node==null)
                return;
            //每次遇到节点,nodeNum+1
            nodeNum++;
            preOrder(node.left);
            preOrder(node.right);
        }
    }