0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

二叉树的最小深度

算法与数据结构 来源:代码随想录 作者:代码随想录 2022-04-28 16:27 次阅读

和求最大深度一个套路?

111.二叉树的最小深度

题目地址:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/

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

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

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

示例:

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

27d8a3d6-c6a8-11ec-bce3-dac502259ad0.png

返回它的最小深度 2.

思路

看完了这篇104.二叉树的最大深度,再来看看如何求最小深度。

直觉上好像和求最大深度差不多,其实还是差不少的。

遍历顺序上依然是后序遍历(因为要比较递归返回之后的结果),但在处理中间节点的逻辑上,最大深度很容易理解,最小深度可有一个误区,如图:

27ed27fc-c6a8-11ec-bce3-dac502259ad0.png

这就重新审题了,题目中说的是:最小深度是从根节点到最近叶子节点的最短路径上的节点数量。,注意是叶子节点

什么是叶子节点,左右孩子都为空的节点才是叶子节点!

递归法

来来来,一起递归三部曲:

  1. 确定递归函数的参数和返回值

参数为要传入的二叉树根节点,返回的是int类型的深度。

代码如下:

intgetDepth(TreeNode*node)
  1. 确定终止条件

终止条件也是遇到空节点返回0,表示当前节点的高度为0。

代码如下:

if(node==NULL)return0;
  1. 确定单层递归的逻辑

这块和求最大深度可就不一样了,一些同学可能会写如下代码:

intleftDepth=getDepth(node->left);
intrightDepth=getDepth(node->right);
intresult=1+min(leftDepth,rightDepth);
returnresult;

这个代码就犯了此图中的误区:

27ed27fc-c6a8-11ec-bce3-dac502259ad0.png

如果这么求的话,没有左孩子的分支会算为最短深度。

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

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

代码如下:

intleftDepth=getDepth(node->left);//左
intrightDepth=getDepth(node->right);//右
//中
//当一个左子树为空,右不为空,这时并不是最低点
if(node->left==NULL&&node->right!=NULL){
return1+rightDepth;
}
//当一个右子树为空,左不为空,这时并不是最低点
if(node->left!=NULL&&node->right==NULL){
return1+leftDepth;
}
intresult=1+min(leftDepth,rightDepth);
returnresult;

遍历的顺序为后序(左右中),可以看出:求二叉树的最小深度和求二叉树的最大深度的差别主要在于处理左右孩子不为空的逻辑。

整体递归代码如下:

classSolution{
public:
intgetDepth(TreeNode*node){
if(node==NULL)return0;
intleftDepth=getDepth(node->left);//左
intrightDepth=getDepth(node->right);//右
//中
//当一个左子树为空,右不为空,这时并不是最低点
if(node->left==NULL&&node->right!=NULL){
return1+rightDepth;
}
//当一个右子树为空,左不为空,这时并不是最低点
if(node->left!=NULL&&node->right==NULL){
return1+leftDepth;
}
intresult=1+min(leftDepth,rightDepth);
returnresult;
}

intminDepth(TreeNode*root){
returngetDepth(root);
}
};

精简之后代码如下:

classSolution{
public:
intminDepth(TreeNode*root){
if(root==NULL)return0;
if(root->left==NULL&&root->right!=NULL){
return1+minDepth(root->right);
}
if(root->left!=NULL&&root->right==NULL){
return1+minDepth(root->left);
}
return1+min(minDepth(root->left),minDepth(root->right));
}
};

精简之后的代码根本看不出是哪种遍历方式,所以依然还要强调一波:如果对二叉树的操作还不熟练,尽量不要直接照着精简代码来学。

迭代法

相对于104.二叉树的最大深度,本题还可以使用层序遍历的方式来解决,思路是一样的。

如果对层序遍历还不清楚的话,可以看这篇:二叉树:层序遍历登场!

需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点

代码如下:(详细注释)

classSolution{
public:

intminDepth(TreeNode*root){
if(root==NULL)return0;
intdepth=0;
queueque;
que.push(root);
while(!que.empty()){
intsize=que.size();
depth++;//记录最小深度
for(inti=0;i< size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
if(!node->left&&!node->right){//当左右孩子都为空的时候,说明是最低点的一层了,退出
returndepth;
}
}
}
returndepth;
}
};

其他语言版本

Java

classSolution{
/**
*递归法,相比求MaxDepth要复杂点
*因为最小深度是从根节点到最近**叶子节点**的最短路径上的节点数量
*/
publicintminDepth(TreeNoderoot){
if(root==null){
return0;
}
intleftDepth=minDepth(root.left);
intrightDepth=minDepth(root.right);
if(root.left==null){
returnrightDepth+1;
}
if(root.right==null){
returnleftDepth+1;
}
//左右结点都不为null
returnMath.min(leftDepth,rightDepth)+1;
}
}
classSolution{
/**
*迭代法,层序遍历
*/
publicintminDepth(TreeNoderoot){
if(root==null){
return0;
}
Dequedeque=newLinkedList<>();
deque.offer(root);
intdepth=0;
while(!deque.isEmpty()){
intsize=deque.size();
depth++;
for(inti=0;i< size; i++) {
                TreeNode poll = deque.poll();
                if(poll.left==null&&poll.right==null){
//是叶子结点,直接返回depth,因为从上往下遍历,所以该值就是最小值
returndepth;
}
if(poll.left!=null){
deque.offer(poll.left);
}
if(poll.right!=null){
deque.offer(poll.right);
}
}
}
returndepth;
}
}

Python

递归法:

classSolution:
defminDepth(self,root:TreeNode)->int:
ifnotroot:
return0
ifnotroot.leftandnotroot.right:
return1

min_depth=10**9
ifroot.left:
min_depth=min(self.minDepth(root.left),min_depth)#获得左子树的最小高度
ifroot.right:
min_depth=min(self.minDepth(root.right),min_depth)#获得右子树的最小高度
returnmin_depth+1

迭代法:

classSolution:
defminDepth(self,root:TreeNode)->int:
ifnotroot:
return0
que=deque()
que.append(root)
res=1

whileque:
for_inrange(len(que)):
node=que.popleft()
#当左右孩子都为空的时候,说明是最低点的一层了,退出
ifnotnode.leftandnotnode.right:
returnres
ifnode.leftisnotNone:
que.append(node.left)
ifnode.rightisnotNone:
que.append(node.right)
res+=1
returnres
--- EOF ---

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 节点
    +关注

    关注

    0

    文章

    216

    浏览量

    24355
  • 函数
    +关注

    关注

    3

    文章

    4276

    浏览量

    62303
  • 二叉树
    +关注

    关注

    0

    文章

    74

    浏览量

    12302

原文标题:二叉树的最小深度!

文章出处:【微信号:TheAlgorithm,微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    什么是默克尔(Merkle Tree)?如何计算默克尔根?

    01 默克尔的概念 默克尔(Merkle Tree)是一种特殊的二叉树,它的每个节点都存储了一个数据块的哈希值。哈希值是一种可以将任意长度的数据转换为固定长度的字符串的算法,它具有唯一性和不可
    的头像 发表于 09-30 18:22 437次阅读
    什么是默克尔<b class='flag-5'>树</b>(Merkle Tree)?如何计算默克尔根?

    指电极上覆盖敏感材料的阻值计算

    覆盖的敏感材料厚度超出指厚度时计算电阻,是否可以视作指电极指间电阻多个周期串联后与超出指厚度部分敏感材料电阻并联
    发表于 07-05 14:48

    指MOSFET器件静电防护鲁棒性提升技巧

    栅极接地NMOS是一种广泛应用的片上ESD器件结构,为达到特定ESD防护等级,一般会采用多指版图形式来减小器件占用的芯片面积。但是,多指栅极接地NMOS在ESD应力作用下,各个指难于做到均匀
    的头像 发表于 06-22 00:50 442次阅读
    多<b class='flag-5'>叉</b>指MOSFET器件静电防护鲁棒性提升技巧

    示波器怎么设置存储深度

    存储深度,也称为记录长度,是指示波器能够连续捕获和存储的采样点数。它决定了示波器能够捕获的波形的时间长度,以及能够分辨的最小时间间隔。
    的头像 发表于 05-31 15:42 1253次阅读

    原理图设计里两颗重要的(国产EDA)

    原理图里面两颗重要的,那就是元件和网络,作为EDA工具中的重要视图和概念,虽然看似枯燥,但它们扮演着非常重要的角色,它们为电路图的层次化结构提供了有力支撑。想象一个大型的电路设计项目,就像一个
    的头像 发表于 05-29 17:47 642次阅读
    原理图设计里两颗重要的<b class='flag-5'>树</b>(国产EDA)

    华睿科技近期推出新一代堆高式取型AMR FD150

    华睿科技近期推出新一代堆高式取型AMR FD150。FD150基于AMR专用车身设计,额定负载1500KG,最大举升高度2m,满足最小2.2m通道内自主识别取放货。
    的头像 发表于 03-25 09:46 495次阅读

    哈夫曼编码怎么算 哈夫曼编码左边是0还是1

    二叉树,将出现频率高的字符用较短的编码表示,而出现频率低的字符则用较长的编码表示。通过这种方式,可以实现对数据进行高效的编码和解码。 下面我们将详细介绍哈夫曼编码的算法过程。 统计字符频率 在进行哈夫曼编码前,首先需
    的头像 发表于 01-30 11:27 2367次阅读

    如何修改内核设备

    如何修改内核设备
    的头像 发表于 12-14 14:06 742次阅读
    如何修改内核设备<b class='flag-5'>树</b>

    时钟是什么?介绍两种时钟树结构

    今天来聊一聊时钟。首先我先讲一下我所理解的时钟是什么,然后介绍两种时钟树结构。
    的头像 发表于 12-06 15:23 1537次阅读

    数字IC设计中的分段时钟综合

    为什么需要分段去做时钟呢?因为在某些情况下,按照传统的方法让每一个clock group单独去balance,如果不做额外干预,时钟天然是做不平的。
    的头像 发表于 12-04 14:42 1747次阅读
    数字IC设计中的分段时钟<b class='flag-5'>树</b>综合

    堆的实现思路

    什么是堆? 堆是一种 基于树结构的数据结构,它是一棵二叉树 ,具有以下两个特点: 堆是一个完全二叉树,即除了最后一层,其他层都是满的,最后一层从左到右填满。 堆中每个节点都满足堆的特性,即父节点的值
    的头像 发表于 11-24 16:02 374次阅读
    堆的实现思路

    二叉树的定义

    型结构 是一类重要的 非线性数据结构 ,其中以二叉树最为常用,直观来看,是以分支关系定义的层次结构。型结构在客观世界中广泛存在,比
    的头像 发表于 11-24 15:57 1226次阅读
    <b class='flag-5'>树</b>与<b class='flag-5'>二叉树</b>的定义

    OP-TEE安全存储安全文件的格式

    时,默认情况下, 加密后的数据会被保存在/data/tee目录中。 安全存储功能使用 二叉树的方式来 保存加密后的文件。 当第一次使用安全存储功能创建用于保存敏感数据的安全文件时,OP-TEE将会在/data/tee目录中生成两个文件:dirf.db文件和以数字命名的文件。 dirf.db文
    的头像 发表于 11-21 11:49 680次阅读
    OP-TEE安全存储安全文件的格式

    什么情况下需要布隆过滤器

    , gmail等邮箱垃圾邮件过滤功能 这几个例子有一个共同的特点:如何判断一个元素是否存在一个集合中? 常规思路 数组 链表 、平衡二叉树、Trie Map (红黑) 哈希表 虽然上面描述的这几种数据结构配合常见的排序、
    的头像 发表于 11-11 11:37 621次阅读
    什么情况下需要布隆过滤器

    红黑的特点及应用

    比起理解红黑的原理,更重要的是理解红黑的应用场景,因为某些应用场景的需要,红黑才会应运而生。 红黑的特点: 插入,删除,查找都是O(logn)的复杂度。 红黑
    的头像 发表于 11-10 11:16 684次阅读
    红黑<b class='flag-5'>树</b>的特点及应用