Java算法篇-LeetCode-104-二叉树的最大深度

Java算法篇-LeetCode-104-二叉树的最大深度

    • 1.1 题目
    • 1.2 题解
      • 1.2.1 定义一个二叉树
      • 1.2.2 构造二叉树
      • 1.2.3 计算二叉树的最大深度
    • 1.3 完整测试源码
  • 0x02 参考资料

1.1 题目

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

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3

1.2 题解

1.2.1 定义一个二叉树

根据题意,我们先来定义一个二叉树。

在C语言中是通过结构体类型类实现二叉树的,而在Java中,由于万事万物皆为对象,因此可以通过一个类来定义它。

/**
* 定义一个二叉树
* */
public  class TreeNode{
        /**
         * 值
         */
        int val;
        /**
         * 左孩子
         */
        TreeNode left;
        /**
         * 右孩子
         */
        TreeNode right;

        /**
         * 构造方法
         * @param x
         */
        TreeNode(int x){
            this.val=x;
        }
    }

1.2.2 构造二叉树

然后第二个问题是如何构造这个二叉树,设计思路如下:

 /**
     * 如何用Java对象构造这个二叉树
     * 示例如下:
     * 给定二叉树 [3,9,20,null,null,15,7],
     *     3
     *    / \
     *   9  20
     *     /  \
     *    15   7
     * @return
     */
    private TreeNode initTreeNodeData(){
        //中序遍历 根结点-左孩子-右孩子遍历顺序
        //根结点是3
        TreeNode treeNode=new TreeNode(3);
        //左孩子是9
        treeNode.left=new TreeNode(9);
        //右边孩子是20
        treeNode.right=new TreeNode(20);
        //右边孩子的左边是15
        treeNode.right.left=new TreeNode(15);
        //右边孩子的右边是7
        treeNode.right.right=new TreeNode(7);
        return treeNode;
    }

1.2.3 计算二叉树的最大深度

递归写法和注释如下所示:

/**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public int maxDepth(TreeNode root) {
        //如果根结点为空
        if (null == root) {
            //即二叉树的最大深度为0
            return 0;
        } else {
            //递归调用
            //获取左孩子的深度
            int left_height = maxDepth(root.left);
            //获取右孩子的深度
            int right_height = maxDepth(root.right);
            //java.lang.Math.max(参数1,参数2)是一个静态的工具方法,主要用来比较两个相同类型参数的大小,
            // 支持的类型有double,float,int,long四种类型

            // 只要左边孩子或者右边孩子不为空则深度+1
            // 返回两个数字中最大的那一个
            return Math.max(left_height, right_height) + 1;
        }
    }

复杂度分析

  • 时间复杂度:我们每个结点只访问一次,因此时间复杂度为 O(N)O(N), 其中 N 是结点的数量。
  • 空间复杂度:在最糟糕的情况下,树是完全不平衡的,例如每个结点只剩下左子结点,递归将会被调用 NN 次(树的高度),因此保持调用栈的存储将是O(N)O(N)。但在最好的情况下(树是完全平衡的),树的高度将是 \log(N)log(N)。因此,在这种情况下的空间复杂度将是O(\log(N))O(log(N))。

非递归写法算法如下:

    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        //BFS的层次遍历思想,记录二叉树的层数,
        //遍历完,层数即为最大深度
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        int maxDepth = 0;
        while (!queue.isEmpty()) {
            //每遍历完一个TreeNode 层数加一
            maxDepth++;
            int levelSize = queue.size();
            for (int i = 0; i < levelSize; i++) {
                //检查每一个节点
                TreeNode node = queue.pollFirst();
                //检查是否有左孩子
                if (node.left != null) {
                    queue.add(node.left);
                }
                //检查是否有右孩子
                if (node.right != null) {
                    queue.add(node.right);
                }
            }
        }
        return maxDepth;
    }

1.3 完整测试源码

完整测试源码如下:

import lombok.extern.slf4j.Slf4j;

/**
 * 获取树的深度
 * @author qing-feng.zhao
 */
@Slf4j
public class GetBinaryTreeDepthSolution {
    /**
     * 给定一个二叉树,找出其最大深度。
     *
     * 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
     *
     * 说明: 叶子节点是指没有子节点的节点。
     *
     * 示例:
     * 给定二叉树 [3,9,20,null,null,15,7],
     *
     *     3
     *    / \
     *   9  20
     *     /  \
     *    15   7
     * 返回它的最大深度 3 。
     * @param args
     */
    public static void main(String[] args) {
        //根据题意实例化数组
        Integer[] data={3,9,20,null,null,15,7};
        //由于都是实例方法需要创建一个实例对象
        GetBinaryTreeDepthSolution getBinaryTreeDepthSolution =new GetBinaryTreeDepthSolution();
        //获取初始化好的二叉树
        TreeNode treeNode=getBinaryTreeDepthSolution.initTreeNodeData();

        //我们需要编写的核心算法
        int deep= getBinaryTreeDepthSolution.maxDepth(treeNode);

        //打印结果
        log.info("返回它的最大深度 {}",deep);
    }


    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public int maxDepth(TreeNode root) {
        //如果根结点为空
        if (null == root) {
            //即二叉树的最大深度为0
            return 0;
        } else {
            //递归调用
            //获取左孩子的深度
            int left_height = maxDepth(root.left);
            //获取右孩子的深度
            int right_height = maxDepth(root.right);
            //java.lang.Math.max(参数1,参数2)是一个静态的工具方法,主要用来比较两个相同类型参数的大小,
            // 支持的类型有double,float,int,long四种类型
            
            // 只要左边孩子或者右边孩子不为空则深度+1
            // 返回两个数字中最大的那一个
            return Math.max(left_height, right_height) + 1;
        }
    }
    /**
     * 如何用Java对象构造这个二叉树
     * 示例如下:
     * 给定二叉树 [3,9,20,null,null,15,7],
     *     3
     *    / \
     *   9  20
     *     /  \
     *    15   7
     * @return
     */
    private TreeNode initTreeNodeData(){
        //根结点-左孩子-右孩子遍历顺序
        //根结点是3
        TreeNode treeNode=new TreeNode(3);
        //左孩子是9
        treeNode.left=new TreeNode(9);
        //右边孩子是20
        treeNode.right=new TreeNode(20);
        //右边孩子的左边是15
        treeNode.right.left=new TreeNode(15);
        //右边孩子的右边是7
        treeNode.right.right=new TreeNode(7);
        return treeNode;
    }
    /**
     * 定义一个二叉树
     */
    class TreeNode{
        /**
         * 值
         */
        int val;
        /**
         * 左孩子
         */
        TreeNode left;
        /**
         * 右孩子
         */
        TreeNode right;

        /**
         * 构造方法
         * @param x
         */
        TreeNode(int x){
            this.val=x;
        }
    }
}

执行后输出结果如下:
在这里插入图片描述

0x02 参考资料

  • LeetCode 官方题解
  • JAVA里的Math.max()怎么用?
  • java实现,三种方法,递归实现、迭代实现(DFS、BFS)

你可能感兴趣的:(#,Java,算法修炼手册)