这是悦乐书的第164次更新,第166篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第23题(顺位题号是104)。给定二叉树,找到它的最大深度。最大深度是从根节点到最远叶节点的最长路径上的节点数。叶子是没有子节点的节点。

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

    3
/ \
9 20
/ \
15 7

返回其深度= 3。

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

最大深度是根节点到最远的叶子节点路径上包含的节点数,以上面的二叉树为例,最长路径有两条:3->20->15,3->20->7,这两条路径上的节点数都是3个,所以最后得出其深度是3的结论。

特殊情况一:当传入的二叉树为空时,它没有任何节点,它的深度是0。

特殊情况二:只有根节点的时候,它的深度是1,只有它自身一个节点。

正常情况:我们可以一步一步试着推导下,一个简单的二叉树深度计算过程,还是以上面的二叉树为例。

从根节点开始,此时节点数为1,因为只有它一个节点。

进入根节点的子节点,此时最长路径就是计算9这个左子节点和20这个右子节点的最长路径,显然9是一个叶子节点,只有本身一个节点;而20拥有自己的子节点,此时就需要算出从20出发的最长路径。

20有左子节点15,右子节点7,这时需要继续计算15和7的最长路径,而15和7都是叶子节点,所以节点数只有1,再加上20节点本身这个属于根节点的子节点,20节点的最长路径就是2。

同为3根节点的两个子节点9、20,子节点9的最长路径上节点数为1,子节点20的最长路径上节点数为2,取最大值后,再加上根节点自身的节点数,1+2=3,3就是最长路径上的节点数,也就是该二叉树的深度。

分析到这里,我们知道了,要计算从根节点到最远叶子节点的节点个数,就需要先计算其左右子节点的最长路径,而要计算左右子节点的最长路径,就需要计算他们自身下面的左右子节点的最长路径了,对此我们可以使用递归,算完最下面叶子节点的个数后,再层层往上求其最大值。

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

03 第二种解法

既然可以使用递归,那我们也可以试着使用遍历的方法。从根节点开始,自顶向下遍历子节点,对此使用队列来临时存储每次遍历的子节点,遍历完一层子节点就加1,直到所有子节点都遍历完。

public int maxDepth2(TreeNode root) {
if (root == null) {
return 0;
}
int depth = 0;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
Queue<TreeNode> tem = new LinkedList<>();
while(!q.isEmpty()){
TreeNode node = q.poll();
if (node.left != null) {
tem.offer(node.left);
}
if (node.right != null) {
tem.offer(node.right);
}
}
q = tem;
depth++;
}
return depth;
}

特殊情况还是和第一种解法一样,内层while循环是遍历每层的子节点。

04 第三种解法

第二种解法的内层循环那里,我们使用了新的队列来接收每次循环要进入的下一层节点数据,是否可以改动下,使其更加的简洁?这里我们使用队列的大小来控制它,从根节点开始,进入队列后,队列的size为1,开始进入内层循环,内层循环走了一次后,队列里又多了两个子节点,此时的size为2,然后继续开始内层循环,直到所有的子节点遍历完。

public int maxDepth3(TreeNode root) {
if (root == null) {
return 0;
}
int depth = 0;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
int n = q.size();
while(n-- > 0){
TreeNode node = q.poll();
if (node.left != null) {
q.offer(node.left);
}
if (node.right != null) {
q.offer(node.right);
}
}
depth++;
}
return depth;
}

05 验证与测试

对于上面的两种解法,使用了一个简单的二叉树做了数据测试。

public static void main(String[] args) {
Easy_104_MaximumDepthOfBinaryTree instance = new Easy_104_MaximumDepthOfBinaryTree();
TreeNode t = new TreeNode(1);
TreeNode t2 = new TreeNode(2);
TreeNode t3 = new TreeNode(3);
TreeNode t4 = new TreeNode(4);
TreeNode t5 = new TreeNode(5);
TreeNode t6 = new TreeNode(6);
TreeNode t7 = new TreeNode(7);
TreeNode t8 = new TreeNode(8);
t.left = t2;
t.right = t3;
t2.left = t4;
t2.right = t5;
t3.left = t6;
t3.right = t7;
t7.left = t8;
long start = System.nanoTime();
int result = instance.maxDepth(t);
long end = System.nanoTime();
System.out.println("maxDepth---输出:"+result+" , 用时:"+(end-start)/1000+"微秒");
long start2 = System.nanoTime();
int result2 = instance.maxDepth2(t);
long end2 = System.nanoTime();
System.out.println("maxDepth2---输出:"+result2+" , 用时:"+(end2-start2)/1000+"微秒");
long start3 = System.nanoTime();
int result3 = instance.maxDepth3(t);
long end3 = System.nanoTime();
System.out.println("maxDepth3---输出:"+result3+" , 用时:"+(end3-start3)/1000+"微秒");
}

测试结果如下:

maxDepth---输出:4 , 用时:23微秒
maxDepth2---输出:4 , 用时:586微秒
maxDepth3---输出:4 , 用时:16微秒

从测试的结果可以看出,遍历和递归都是可以解决问题的,第二种解法因为每进一次循环都要创建新的对象,这对内存和运行时间都是不小的消耗,经过优化后第三种解法更加适合遍历使用。

06 小结

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

LeetCode算法题-Maximum Depth of Binary Tree的更多相关文章

  1. LeetCode算法题-Maximum Depth of N-ary Tree(Java实现)

    这是悦乐书的第261次更新,第274篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第128题(顺位题号是559).给定n-ary树,找到它的最大深度.最大深度是从根节点到 ...

  2. LeetCode算法题-Minimum Depth of Binary Tree(Java实现)

    这是悦乐书的第168次更新,第170篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第27题(顺位题号是111).给定二叉树,找到它的最小深度.最小深度是沿从根节点到最近的 ...

  3. 【LeetCode练习题】Maximum Depth of Binary Tree

    Maximum Depth of Binary Tree Given a binary tree, find its maximum depth. The maximum depth is the n ...

  4. 【LeetCode】104. Maximum Depth of Binary Tree (2 solutions)

    Maximum Depth of Binary Tree  Given a binary tree, find its maximum depth. The maximum depth is the ...

  5. 【LeetCode】104. Maximum Depth of Binary Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:BFS 方法二:DFS 参考资料 日期 题目 ...

  6. 【一天一道LeetCode】#104. Maximum Depth of Binary Tree

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 来源:http ...

  7. LeetCode算法题-Construct String from Binary Tree(Java实现)

    这是悦乐书的第273次更新,第288篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第141题(顺位题号是606).构造一个字符串,该字符串由二叉树中的括号和整数组成,并具 ...

  8. 【LeetCode】104 - Maximum Depth of Binary Tree

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  9. [LeetCode#104, 111]Maximum Depth of Binary Tree, Minimum Depth of Binary Tree

    The problem 1: Given a binary tree, find its maximum depth. The maximum depth is the number of nodes ...

随机推荐

  1. VRF在区块链中的应用

    最近区块链领域流行了一种"怪病",许多区块链项目或者设计方案都加入了一个叫做VRFs的算法.那么, (1) 什么是VRFs? (2) VRFs在区块链中解决了什么问题? 本文旨在介 ...

  2. Packet for query is too large (12238 > 1024). You can change this value

    MySQL max_allowed_packet 设置过小导致记录写入失败 mysql根据配置文件会限制server接受的数据包大小. 有时候大的插入和更新会受max_allowed_packet 参 ...

  3. SharedPreferences存储读取数据

    存储 //创建SharedPreferences 存储用户名SharedPreferences sharedPreferences = getSharedPreferences("name& ...

  4. 【问题】vs IIS破除文件上传限制最全版

    今天在测试一下上传文件的时候发现iis和配置存在上传文件大小限制(IIS默认大小30M,最大运行为2g:2147483647),百度了一部分资料有些发布到IIS好使,但是在VS调试中不好使.于是自己不 ...

  5. 程序猿制造Bug的根本原因竟然是....

    传说中: 「杀一个程序猿不需要用枪,改三次需求就可以了.」 而且, 「这竟然也是程序猿制造Bug的根本原因....」 ↓↓↓↓↓↓↓ #/原始需求/#   你去饭店,坐下来. “服务员,给我来份宫保鸡 ...

  6. 汇编语言--微机CPU的指令系统(五)(算术运算指令)

    (3)算术运算指令 算术运算指令是反映CPU计算能力的一组指令,也是编程时经常使用的一组指令.它包括:加.减.乘.除及其相关的辅助指令. 该组指令的操作数可以是8位.16位和32位(80386+).当 ...

  7. Fundebug累计处理1000万条错误事件!

    摘要上线半年时间,Fundebug累计处理1000万条错误事件.10000000啊! 自从去年双11[正式上线](https://blog.fundebug.com/2016/11/11/fundeb ...

  8. vue2 兼容ie8

    推荐这个 https://cdn.jsdelivr.net/npm/ractive

  9. CSS制作镂空字体

    1.效果图 2.html内容: <!doctype html><html lang="en"><head> <meta charset=& ...

  10. JavaScript之Number、String、Array常用属性与方法手册

    Number isFinite函数 Number.isFinite() 方法用来检测传入的参数是否是一个有穷数(finite number). 语法: Number.isFinite(value) 例 ...