LeetCode算法题-Maximum Depth of Binary Tree
这是悦乐书的第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的更多相关文章
- LeetCode算法题-Maximum Depth of N-ary Tree(Java实现)
这是悦乐书的第261次更新,第274篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第128题(顺位题号是559).给定n-ary树,找到它的最大深度.最大深度是从根节点到 ...
- LeetCode算法题-Minimum Depth of Binary Tree(Java实现)
这是悦乐书的第168次更新,第170篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第27题(顺位题号是111).给定二叉树,找到它的最小深度.最小深度是沿从根节点到最近的 ...
- 【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 ...
- 【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 ...
- 【LeetCode】104. Maximum Depth of Binary Tree 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:BFS 方法二:DFS 参考资料 日期 题目 ...
- 【一天一道LeetCode】#104. Maximum Depth of Binary Tree
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 来源:http ...
- LeetCode算法题-Construct String from Binary Tree(Java实现)
这是悦乐书的第273次更新,第288篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第141题(顺位题号是606).构造一个字符串,该字符串由二叉树中的括号和整数组成,并具 ...
- 【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 ...
- [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 ...
随机推荐
- SQL行转列:decode函数
前言 开发中我们经常会用到行转列,这里记录一下我在项目中实现行转列的思路.需求:报表模块,统计某机房机架的不同状态(1 空闲 2 预占 3 占用)的数量(真实需求更为复杂,这里只是讨论技术,简化一 ...
- Layui table 组件的使用:初始化加载数据、数据刷新表格、传参数
背景 笔者之前一直使用 bootstrap table ,因为当前项目中主要使用 Layui 框架,于是也就随了 Layui table ,只是在使用的时候出现了一些问题,当然也是怪自己不熟悉的锅吧! ...
- vsCode 列选择、列选中、选中列、选中多列(转载)
VSCode列选择快捷键 来源 https://blog.csdn.net/Luyanc/article/details/80502069 VSCode列选择快捷键:Alt+Shift+左键 来一张效 ...
- 【Java每日一题】20170222
20170221问题解析请点击今日问题下方的“[Java每日一题]20170222”查看(问题解析在公众号首发,公众号ID:weknow619) package Feb2017; import jav ...
- 全网最贴心webpack系列教程和配套代码
webpack-demos:全网最贴心 webpack 系列教程和配套代码 欢迎关注个人技术博客:godbmw.com.每周 1 篇原创技术分享!开源教程(webpack.设计模式).面试刷题(偏前端 ...
- 持续集成 自动化构建、测试、部署您的Coding代码
持续集成(Continuous Integration)指的是,频繁地(一天多次)将代码集成到主干. 持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量. 它的核心措施是,代码集成到主干之前, ...
- css 小知识点:inline/inline-block/line-height
inline: 此元素会被显示为内联元素,元素前后没有换行符.因此:无法设置宽度和高度- inline-block: 行内块元素.元素前后没有换行符(CSS2.1 新增的值) 用通俗的话讲,就是不独占 ...
- js 依据“;”折行
function roomIds(roomid) { // var str = roomid.replace(/;/g,'\r\n'); if (roomid) { var str = roomid. ...
- Spring学习之旅(六)Spring AOP工作原理初探
AOP(Aspect-Oriented Programming,面向切面编程)是Spring提供的关键技术之一. AOP基于IoC,是对OOP(Object-Oriented Programming ...
- Android为TV端助力 关于线程的那些事
今天发现之前自己一直有个误区,new Runnable(run()方法){}原来它不是一定创建一个线程 如果用主线程的handler去post(Runnable),他就不会创建子线程,而是在主线程上执 ...