牛客题解 | 二叉树的深度

news/2025/2/25 16:17:18/文章来源:https://www.cnblogs.com/wc529065/p/18736588

题目

题目链接

题目的主要信息:
  • 给定一棵二叉树的根节点,求这棵树的最大深度
  • 深度是指树的根节点到任一叶子节点路径上节点的数量
  • 最大深度是所有叶子节点的深度的最大值
  • 叶子节点是指没有子节点的节点
举一反三:

学习完本题的思路你可以解决如下题目:

JZ82. 二叉树中和为某一值的路径(一)

JZ28. 对称的二叉树

JZ27. 二叉树的镜像

JZ79. 判断是不是平衡二叉树

JZ37. 序列化二叉树

方法一:递归(推荐使用)

知识点:二叉树递归

递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此递归过程,最重要的就是查看能不能讲原本的问题分解为更小的子问题,这是使用递归的关键。

而二叉树的递归,则是将某个节点的左子树、右子树看成一颗完整的树,那么对于子树的访问或者操作就是对于原树的访问或者操作的子问题,因此可以自我调用函数不断进入子树。

思路:

最大深度是所有叶子节点的深度的最大值,深度是指树的根节点到任一叶子节点路径上节点的数量,因此从根节点每次往下一层深度就会加1。因此二叉树的深度就等于根节点这个1层加上左子树和右子树深度的最大值,即\(root_{depth} = max(left_{depth}, right_{depth})+1\)。而每个子树我们都可以看成一个根节点,继续用上述方法求的深度,于是我们可以对这个问题划为子问题,利用递归来解决:

  • 终止条件: 当进入叶子节点后,再进入子节点,即为空,没有深度可言,返回0.
  • 返回值: 每一级按照上述公式,返回两边子树深度的最大值加上本级的深度,即加1.
  • 本级任务: 每一级的任务就是进入左右子树,求左右子树的深度。

具体做法:

  • step 1:对于每个节点,若是不为空才能累计一次深度,若是为空,返回深度为0.
  • step 2:递归分别计算左子树与右子树的深度。
  • step 3:当前深度为两个子树深度较大值再加1。

图示:

alt

Java实现代码:

import java.util.*;
public class Solution {public int maxDepth (TreeNode root) {//空节点没有深度if(root == null) return 0;//返回子树深度+1return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; }
}

C++实现代码:

class Solution {
public:int maxDepth(TreeNode* root) {//空节点没有深度if(root == NULL) return 0;//返回子树深度+1return max(maxDepth(root->left), maxDepth(root->right)) + 1; }
};

Python实现代码

class Solution:def maxDepth(self , root: TreeNode) -> int:# 空节点没有深度if not root: return 0# 返回子树深度+1return max([self.maxDepth(root.left), self.maxDepth(root.right)]) + 1

复杂度分析:

  • 时间复杂度:\(O(n)\),其中\(n\)为二叉树的节点数,遍历整棵二叉树
  • 空间复杂度:\(O(n)\),最坏情况下,二叉树化为链表,递归栈深度最大为\(n\)
方法二:层次遍历(扩展思路)

知识点:队列

队列是一种仅支持在表尾进行插入操作、在表头进行删除操作的线性表,插入端称为队尾,删除端称为队首,因整体类似排队的队伍而得名。它满足先进先出的性质,元素入队即将新元素加在队列的尾,元素出队即将队首元素取出,它后一个作为新的队首。

思路:

既然是统计二叉树的最大深度,除了根据路径到达从根节点到达最远的叶子节点以外,我们还可以分层统计。对于一棵二叉树而言,必然是一层一层的,那一层就是一个深度,有的层可能会很多节点,有的层如根节点或者最远的叶子节点,只有一个节点,但是不管多少个节点,它们都是一层。因此我们可以使用层次遍历,二叉树的层次遍历就是从上到下按层遍历,每层从左到右,我们只要每层统计层数即是深度。

具体做法:

  • step 1:既然是层次遍历,我们遍历完一层要怎么进入下一层,可以用队列记录这一层中节点的子节点。队列类似栈,只不过是一个先进先出的数据结构,可以理解为我们平时的食堂打饭的排队。因为每层都是按照从左到右开始访问的,那自然记录的子节点也是从左到右,那我们从队列出来的时候也是从左到右,完美契合。
  • step 2:在刚刚进入某一层的时候,队列中的元素个数就是当前层的节点数。比如第一层,根节点先入队,队列中只有一个节点,对应第一层只有一个节点,第一层访问结束后,它的子节点刚好都加入了队列,此时队列中的元素个数就是下一层的节点数。因此遍历的时候,每层开始统计该层个数,然后遍历相应节点数,精准进入下一层。
  • step 3:遍历完一层就可以节点深度就可以加1,直到遍历结束,即可得到最大深度。

图示:

alt

Java实现代码:

import java.util.*;
public class Solution {public int maxDepth (TreeNode root) {//空节点没有深度if(root == null) return 0;//队列维护层次后续节点Queue<TreeNode> q = new LinkedList<TreeNode>(); //根入队q.offer(root); //记录深度int res = 0; //层次遍历while(!q.isEmpty()){ //记录当前层有多少节点int n = q.size(); //遍历完这一层,再进入下一层for(int i = 0; i < n; i++){ TreeNode node = q.poll();//添加下一层的左右节点if(node.left != null) q.offer(node.left);if(node.right != null)q.offer(node.right);}//深度加1res++; }return res; }
}

C++实现代码:

class Solution {
public:int maxDepth(TreeNode* root) {//空节点没有深度if(root == NULL) return 0;//队列维护层次后续节点queue<TreeNode*> q; //根入队q.push(root); //记录深度int res = 0; //层次遍历while(!q.empty()){ //记录当前层有多少节点int n = q.size(); //遍历完这一层,再进入下一层for(int i = 0; i < n; i++){ TreeNode* node = q.front();q.pop();//添加下一层的左右节点if(node->left) q.push(node->left);if(node->right)q.push(node->right);}//深度加1res++; }return res;}
};

Python实现代码

import queue
class Solution:def maxDepth(self , root: TreeNode) -> int:# 空节点没有深度if not root: return 0# 队列维护层次后续节点q= queue.Queue() # 根入队q.put(root) # 记录深度res = 0# 层次遍历while not q.empty(): # 记录当前层有多少节点n = q.qsize() # 遍历完这一层,再进入下一层for i in range(n): node = q.get()# 添加下一层的左右节点if node.left: q.put(node.left)if node.right:q.put(node.right)# 深度加1res += 1 return res

复杂度分析:

  • 时间复杂度:\(O(n)\),其中\(n\)为二叉树的节点数,遍历整棵二叉树
  • 空间复杂度:\(O(n)\),辅助队列的空间最坏为\(n\)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/889626.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客题解 | 二叉树中和为某一值的路径(三)

牛客题库题解题目 题目链接 题目的主要信息:给定一个二叉树root和一个整数值 sum ,求该树有多少路径的的节点值之和等于 sum 路径定义不需要从根节点开始,也不需要在叶子节点结束,但是一定是从父亲节点往下到孩子节点,如下图所示:举一反三: 学习完本题的思路你可以解决如…

S2-兽王-猎人Hunt-团体-大秘境-专精-天赋-配装-宏

S2毕业装--属性 急速>爆击>精通>全能 急速和爆击越高越好。精通随缘。不要全能。 --团本/单体天赋(更新时间2月10日)--团本/单体天赋代码 C0PAAAAAAAAAAAAAAAAAAAAAAAMmxGDsALDDNsBAAAAAgBAAAAAAYGLDzyMjhxYmZMMjZGjZmZyMMmZmZmxMjZYMmZGGDGzgN --大秘/AOE天赋(更新时…

牛客题解 | 二叉树中和为某一值的路径(二)

牛客题库题解题目 题目链接 题目的主要信息:题目给出我们一棵树的树根结点指针,和一个期待值 我们要找出这棵树中,从根节点到叶子节点的路径上的节点值之和等于该期待值的路径,找出所有这样的路径并返回。举一反三: 学习完本题的思路你可以解决如下题目: JZ82. 二叉树中和…

S2-恩护-唤魔师Evoker-团体-大秘境-专精-天赋-配装-宏

S2毕业装--属性 爆击>急速>精通>全能 爆击,急速和精通的收益非常接近。全能随缘。 --团本天赋(更新时间2月4日)--团本天赋代码 CwbBV7//nP39x/JJympTqouKSAAAAAAYmZMLzghZGzixMbjZGAAwMjZMDGzIMDAAAwMzIsNzMz2MzAAjZDWALgZYCZgNDD --大秘天赋(更新时间2月4日)--大秘天…

牛客题解 | 二叉搜索树的后序遍历序列

牛客题库题解题目 题目链接 题目的主要信息:题目给出我们一个一维数组sequence 该数组需要我们判定数组sequence中的元素是否符合一个二叉搜索树的后序遍历顺序 如果该数组sequence可以是一种二叉搜索树的后序遍历顺序,则返回true 如果该数组sequence非二叉搜索树的后序遍历顺…

FX5U 三菱PLC 增加采集协议

FX5U 三菱PLC 增加采集协议 MC协议,端口只能连一个设备

牛客题解 | 买卖股票的最好时机(一)

牛客题库题解题目 题目链接 题目主要信息:给出一个数组表示连续多日的股票价格 你可以选择在某一天买入股票,在另一天卖出股票,买卖都只有一次机会,不能在同一天 假设买卖没有手续费,问最高收益是多少,即卖出的价格减去买入的价格,如果没有利润需要返回0 可以看成查找数…

牛客题解 | 主持人调度(二)

牛客题库题解题目 题目链接 题目的主要信息:n个活动,有各自的区间 一个主持人不能在相交的区间工作 将相交的区间分成一组,最后组数即是主持人的数量 数字为int型的范围,可能会出现负数举一反三: 学习完本题的思路你可以解决如下题目: BM89. 合并区间 BM95. 分糖果问题 方…

有负环的费用流问题:用消消乐“白嫖”的艺术

前文回顾:https://www.cnblogs.com/ofnoname/p/18731222 想象你是一家快递公司的调度员,每天的任务是将货物从仓库高效送到客户。你设计了一条完美路线:每辆卡车都走最短路径,运费最省,按时送达——直到有一天,某个司机突然上报了一个诡异的现象:“老板,我的卡车在某个…

牛客题解 | 不同路径的数目(一)

牛客题库题解题目 题目链接 题目主要信息:给定一个\(m*n\)的矩阵,要求从矩阵的左上角走到右下角的不同路径数量 每次只能往下或者往右走举一反三: 学习完本题的思路你可以解决如下题目: BM68.矩阵的最小路径和 方法一:递归(推荐使用) 知识点:递归 递归是一个过程或函数在…

牛客题解 | 不用加减乘除做加法

牛客题库题解题目 题目链接 题目的主要信息:题目给出两个数字 我们需要给出两个数字相加的结果 题目要求我们不可以用加减乘除符号 因此与或非运算就是我们可以用的方式举一反三: 学习完本题的思路你可以解决如下题目: JZ15. 二进制中1的个数 JZ56. 数组中只出现一次的两个数…

S2-奥法-法师Mage-奥术-团体-大秘境-专精-天赋-配装-宏

S2毕业装--属性 急速>精通>全能>爆击 急速越高越好。精通的收益略微高于全能。爆击随缘。 --团本/单体天赋(更新时间2月4日)--团本/单体天赋代码 C4DAjd9IgsSkCmGQ8vOmZtyV7YGMbzCmxDMmFDjZGGTzMmBAAAAAgBCACYmZbZZZmJWAAAAAAAALDDzMzMjZYmxYmZMzMjxMG --大秘/AOE天赋…