普通二叉树和右倾斜二叉树--LeetCode 111题《Minimum Depth of Binary Tree》

本文将以解释计算二叉树的最小深度的思路为例,致力于用简洁易懂的语言详细描述普通二叉树和右倾斜二叉树在计算最小深度时的区别。通过跟随作者了解右倾斜二叉树的概念以及其最小深度计算过程,读者也将对左倾斜二叉树有更深入的了解。这将为解决LeetCode 111题《Minimum Depth of Binary Tree》提供有力支持。最终,本文将提供LeetCode 111的解题代码。

题目内容-- Leetcode111. Minimum Depth of Binary Tree

Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. Note: A leaf is a node with no children.

例子1️⃣: 例子2️⃣

输入:root = [3,9,20,null,null,15,7]                    输入:root = [2,null,3,null,4,null,5,null,6]

输出:2                                                              输出:5

题目🔗链接

解题思路分析

  • 普通二叉树

    • 理解问题:首先,理解问题的要求。问题要求找到给定二叉树的最小深度,即从根节点到最近的叶子节点的最短路径上的节点数。
    • 考虑特殊情况:考虑特殊情况,比如空树或只有一个节点的树。对于这些情况,最小深度分别为0或1。
    • 使用递归:采用递归的方式来解决问题。从根节点开始,递归地计算左子树和右子树的最小深度。然后,最小深度是左右子树最小深度的较小值加上1。
    • 处理叶子节点:在递归过程中,需要特别注意处理叶子节点的情况。叶子节点的最小深度是1。

            下面是可能实现的伪代码:           

def minDepth(root):
    # 处理空树的情况
    if root is None:
        return 0

    # 处理叶子节点的情况
    if root.left is None and root.right is None:
        return 1

    # 计算左右子树的最小深度
    left_depth = minDepth(root.left)
    right_depth = minDepth(root.right)

    # 返回最小深度
    return min(left_depth, right_depth) + 1

因此,这个递归算法通过适当的处理,可以灵活地应对不同形态的二叉树,包括右倾斜二叉树和普通二叉树。                

  • 右倾斜二叉树

    1. 定义:右倾斜二叉树(Right-skewed binary tree)是一种特殊的二叉树结构,其中每个非叶子节点只有右子节点,而没有左子节点。这导致树的形状是向右倾斜的,呈现出一种链表的形式。
    2. 右倾斜二叉树的特点包括:(1)每个非叶子节点最多右一个子节点,且该子节点是右子节点。(2)左子树为空,右子树可能为空或者不为空。(3)从根节点到任意叶子节点的路径都只包含右子节点。
    3. 对于右倾斜二叉树,树中的每个节点都只有右子树,递归的方式可以稍微修改一下。在递归计算最小深度时,我们需要考虑到只有右子树的情况。以下的代码可以处理三种情况:(1)普通二叉树;(2)右倾斜二叉树;(3)以右倾斜二叉树开头+普通二叉树的混合结构。
      def minDepth(root):
          # 处理空树的情况
          if root is None:
              return 0
      
          # 递归计算右子树的最小深度
          right_depth = minDepth(root.right)
      
          # 如果左子树为空,说明只有右子树,返回右子树的最小深度加上1
          if root.left is None:
              return right_depth + 1
      
          # 如果左右子树都存在,返回左右子树最小深度的较小值加上1
          return min(minDepth(root.left), right_depth) + 1

      这样的实现考虑了右倾斜二叉树的情况,递归过程会一直沿着右子树向下进行,直到找到叶子节点。同样,返回的最小深度是左右子树最小深度的较小值加上1。

    4. 以上代码之所以能够处理普通二叉树和右倾斜二叉树的情况,是因为在递归计算最小深度的过程中,代码会考虑每个节点的左右子树情况,从而综合考虑了整个树的结构。分布解释为什么会有效:

      1. 递归基准:在递归函数中,首先处理了空树的情况,如果树为空,则返回深度0。

      2. 递归右子树:对于每个非空节点,递归计算右子树的最小深度。这是为了处理右倾斜二叉树,因为在右倾斜二叉树中,节点的左子树可能为空,而右子树不能为空。

      3. 处理只有右子树的情况:在右子树的计算过程中,如果发现左子树为空,那么说明该节点只有右子树,此时返回右子树的最小深度加上1。这是为了处理右倾斜二叉树中,只有右子树的情况。

      4. 处理左右子树都存在的情况:如果左右子树都存在,返回左右子树的最小深度的较小值加上1。这是为了处理普通二叉树的情况。因此,这个递归算法通过适当的处理,可以灵活地应对不同形态的二叉树,包括右倾斜二叉树和普通二叉树。

    5. 右倾斜二叉树示例:
            1
             \
              2
               \
                3
                 \
                  4
      

      在这个例子中,每个节点都只有右子节点,形成了一个向右倾斜的结构。这种树的高度等于节点的数量,因为每个节点都沿着右子节点一直向下。

    6. 混合结构的二叉树:以右倾斜二叉树开头 + 普通二叉树结构:如左图,混合结构二叉树的最小深度为6。使用上述代码计算最小深度时,它将递归计算右倾斜二叉树部分的深度,即节点数为4。然后,它将递归计算二叉树部分的深度,考虑到左右子树的情况,返回左右子树的最小深度的较小值加上 1。同理,右侧为9。
  • 左倾斜二叉树

    1. 为了通过Leetcode 111. Minimum Depth of Binary Tree所有的测试样例,提供能够处理普通二叉树和右倾斜二叉树的最小深度的方案还是不够,还需要能够处理左倾斜二叉树,以及左倾斜二叉树+普通二叉树的混合结构,
    2. 示例样例如下:root=[1,2]。
    3. 为此,我们参照右倾斜二叉树的定义和实现方式,得出来关于左倾斜二叉树的伪代码,如下:
      def minDepth(root):
          # 处理空树的情况
          if root is None:
              return 0
      
          # 递归计算左子树的最小深度
          left_depth = minDepth(root.left)
      
          # 如果右子树为空,说明只有左子树,返回左子树的最小深度加上1
          if root.right is None:
              return left_depth + 1
      
          # 如果左右子树都存在,返回左右子树最小深度的较小值加上1
          return min(left_depth, minDepth(root.right)) + 1
  • 整合思路和代码结果

  • 将以上思路整合起来,我们能得到一个可以解决以下7️⃣个方面的算法,并且能够解决LeetCode 111题《Minimum Depth of Binary Tree》。
    1. 普通二叉树
    2. 右倾斜二叉树
    3. 左倾斜二叉树
    4. 右倾斜二叉树开头+普通二叉树的混合结构
    5. 左倾斜二叉树开头+普通二叉树的混合结构 
    6. 左倾斜和右倾斜的混合结构
    7. 左倾斜或右倾斜二叉树开头+普通二叉树树+左倾斜或右倾斜二叉树混合结构
  • 将以上代码整合成能求解右倾斜,左倾斜和普通二叉树结构的最小树深度的伪代码如下:整合思路和代码结果:
    def minDepth(self, root):
        # 处理空树的情况
        if root is None:
           return 0
            
        # 递归计算右子树的最小深度
        right_depth = self.minDepth(root.right)
        left_depth = self.minDepth(root.left)
            
        # 如果左子树为空,说明只有右子树,返回右子树的最小深度加上1
        if root.left is None:
           return right_depth + 1
            
        # 如果右子树为空,说明只有左子树,返回左子树的最小深度加上1
        if root.right is None:
           return left_depth + 1 
    
        # 如果左右子树都存在,返回左右子树最小深度的较小值加上1
        return min(left_depth, right_depth)+1

  • 时间和空间复杂度

计算二叉树的复杂度涉及两个主要方面:时间复杂度和空间复杂度。这两个复杂度是对算法执行时间和所需内存的度量。

时间复杂度

时间复杂度表示算法执行所需的时间,通常以大O表示法表示。对于二叉树的操作,例如遍历、搜索或修改节点,时间复杂度通常取决于树的高度和节点数量。

在一般情况下:

  • 平均时间复杂度: 对于平均情况下的树,可以考虑使用平均深度和平均节点数来估算。
  • 最坏时间复杂度: 对于最坏情况下的树,通常考虑树的最大深度和节点数。

例如,对于二叉搜索树(BST),查找一个节点的平均时间复杂度为O(logn), 其中n是节点数。在最坏的情况下,树是不平衡的,时间复杂度可能为O(n),其中n是节点树。

空间复杂度

空间复杂度表示算法执行所需的内存空间,也通常以大O表示法表示。对于二叉树,空间复杂度主要取决于递归调用、栈的使用和其他额外数据结构的空间开销。

  • 递归的空间复杂度:在递归遍历二叉树时,递归调用栈的深度影响空间复杂度。平衡二叉树的递归深度通常为O(log n), 而不平衡二叉树的深度可能为O(n)。

  • 其他数据结构的空间复杂度:如果在算法执行中使用了其他数据结构(如队列、堆栈等),则需要考虑这些数据结构的空间开销。

综合考虑递归深度、节点数以及其他数据结构的使用,可以得到二叉树的总体空间复杂度。

需要注意的是,二叉树的具体操作和算法会影响复杂度的具体数值。在分析复杂度时,通常使用大 O 表示法来表示算法的渐进复杂度,即在输入规模趋于无穷大时的复杂度。

二叉树中的堆栈

在二叉树的操作和遍历中,堆栈(stack)通常用于以下几种情况:

  1. 递归(recursive)的实现:二叉树的深度优先搜索(DFS)通常使用递归来实现。递归函数的调用本质上就是使用了堆栈。在递归过程中,每一次递归调用都会将当前状态的信息(比如当前节点、访问过的节点等)压入堆栈,而递归返回时会从堆栈中弹出这些信息,使得递归能够回到上一层。
  2. 非递归的深度优先搜索:除了递归实现,深度优先搜索也可以使用显示的堆栈来模拟递归过程。在迭代版本的深度优先搜索中,通过维护一个堆栈,可以手动模拟递归调用的过程,将当前状态信息入栈、出栈、实现深度遍历。
  3. 迭代(iteration)的广度优先搜索:广度优先搜索(BFS)通常使用队列,但有时也可以使用堆栈,特别是在反向遍历的情况下。在迭代的BFS中,每层的节点可以按照逆序压入堆栈,使得出栈的顺序满足反向的BFS要求。
  4. 中序遍历的非递归实现:在二叉树的中序遍历中的左子树、根节点、右子树的顺序访问。

在这些情况下,堆栈的主要作用是在算法的执行过程中保存状态信息,以便在需要时能够回溯到之前的状态。这对于深度优先搜索、中序遍历等操作是非常有用的。在实际编程中,堆栈的使用可以显示的创建一个堆栈数据结构,也可以使用编程语言自身的调用栈来实现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leaflet.Graticule源码分析以及经纬度汉化展示

目录 前言 一、源码分析 1、类图设计 2、时序调用 3、调用说明 二、经纬度汉化 1、改造前 2、汉化 3、改造效果 总结 前言 在之前的博客基于Leaflet的Webgis经纬网格生成实践中,已经深入介绍了Leaflet.Graticule的实际使用方法和进行了简单的源码分析。认…

Python【Matplotlib】图例可拖动改变位置

代码: import matplotlib.pyplot as plt from matplotlib.widgets import Button# 创建一个示例图形 fig, ax plt.subplots() line, ax.plot([1, 2, 3], labelLine 1)# 添加图例 legend ax.legend(locupper right, draggableTrue)# 添加一个按钮,用于…

媒体直播平台有哪些,活动直播如何扩大曝光?

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 媒体直播平台包括人民视频、新华社现场云、中国网、新浪新闻直播、搜狐视频直播、凤凰新闻直播、腾讯新闻直播等。活动直播想要扩大曝光,可以考虑以下方式: 1.选择…

【深度学习】TensorFlow深度模型构建:训练一元线性回归模型

文章目录 1. 生成拟合数据集2. 构建线性回归模型数据流图3. 在Session中运行已构建的数据流图4. 输出拟合的线性回归模型5. TensorBoard神经网络数据流图可视化6. 完整代码 本文讲解: 以一元线性回归模型为例, 介绍如何使用TensorFlow 搭建模型 并通过会…

数据泄露警报:不同行业危机解析与迅软DSE的拯救之道

在如今全球信息数字化不断加速的时代里,数据资料的价值更为突出,根据IBM数据显示,数据泄露的平均成本接近440万美元。一旦泄露可能意味着丢失信息、声誉受损,并可能导致延误和生产力损失。那么不同行业一旦发生了数据泄露将会面临…

Linux部署MySQL5.7和8.0版本 | CentOS和Ubuntu系统详细步骤安装

一、MySQL数据库管理系统安装部署【简单】 简介 MySQL数据库管理系统(后续简称MySQL),是一款知名的数据库系统,其特点是:轻量、简单、功能丰富。 MySQL数据库可谓是软件行业的明星产品,无论是后端开发、…

Redis——02,redis-benchmark 性能测试

redis-benchmark 性能测试 一、benchmark 性能测试。二、参数详解: 一、benchmark 性能测试。 在bin目录下,有一个redis-benchmark 工具,是用来测试性能的。 二、参数详解: http://doc.yaojieyun.com/www.runoob.com/redis/re…

VMP泄露编译的一些注意事项

VMP编译教程 鉴于VMP已经在GitHub上被大佬强制开源,特此出一期编译教程。各位熟悉的可以略过,不熟悉的可以参考一下。 环境(软件) Visual Studio 2015 - 2022 (建议使用VS2019,Qt插件只有这个版本及以上…

Python等比例缩放图片并修改对应的Labelme标注文件(v2.0)

Python等比例缩放图片并修改对应的Labelme标注文件(v2.0) 前言前提条件相关介绍实验环境Python等比例缩放图片并修改对应的Labelme标注文件Json文件代码实现输出结果 前言 此版代码,相较于Python等比例缩放图片并修改对应的Labelme标注文件&a…

原子学习笔记1——阻塞和非阻塞IO

阻塞式 I/O 顾名思义就是对文件的 I/O 操作(读写操作)是阻塞式的,非阻塞式 I/O 同理就是对文件的I/O 操作是非阻塞的。 当对文件进行读操作时,如果数据未准备好、文件当前无数据可读,那么读操作可能会使调用者阻塞&…

编程实际应用实例:洗车店会员管理系统操作教程

一、前言 洗车店在会员管理有时候需要一卡多用,基本也不需要做卡,直接报手机号或车牌号即可完成电子会员卡录入。 下面以 佳易王洗车店会员管理系统软件为例说明, 软件试用版下载或技术支持可以点击下方的官网卡片 如图:这个卡…

[HCTF 2018]WarmUp (代码审计)

打开题目: 好好好。 看看源码: ? source.php 让我看看! 发现还有个文件叫hint,php 看看: 得到目的文件是ffffllllaaaagggg 分析代码: $_REQUEST 变量 $_REQUEST用于收集HTML表单提交的数据&#x…

迅为RK3568开发板使用OpenCV处理图像-ROI区域-位置提取ROI

在图像处理过程中,我们可能会对图像的某一个特定区域感兴趣,该区域被称为感兴趣区域(Region of Interest, ROI)。在设定感兴趣区域 ROI 后,就可以对该区域进行整体操作。 位置提取 ROI 本小节代码在配套资料“iTOP-3…

RocketMQ系统性学习-RocketMQ领域模型及Linux下单机安装

MQ 之间的对比 三种常用的 MQ 对比,ActiveMQ、Kafka、RocketMQ 性能方面: 三种 MQ 吞吐量级别为:万,百万,十万消息发送时延:毫秒,毫秒,微秒可用性:主从,分…

【深度学习】机器学习概述(一)机器学习三要素——模型、学习准则、优化算法

​ 文章目录 一、基本概念二、机器学习的三要素1. 模型a. 线性模型b. 非线性模型 2. 学习准则a. 损失函数1. 0-1损失函数2. 平方损失函数(回归问题)3. 交叉熵损失函数(Cross-Entropy Loss)4. Hinge 损失函数 b. 风险最小化准则1.…

MQTT 介绍与学习 —— 筑梦之路

之前写过的相关文章: MQTT协议(转载)——筑梦之路_mqtt url-CSDN博客 k8s 部署mqtt —— 筑梦之路-CSDN博客 CentOS 7 搭建mqtt服务——筑梦之路_腾讯云宝塔搭 centos 7.9.2009 x86_64 建标准mqtt服务器-CSDN博客 mqtt简介 MQTT&#xff…

tcp/ip协议2实现的插图,数据结构5 (22 - 章)

(103) 103 二二1 协议控制块 结构 file, socket , rawcb , inpcb , tcpcb 之间的联系 (104) (105)

Python:如何将MCD12Q1\MOD11A2\MOD13A2原始数据集批量输出为TIFF文件(镶嵌/重投影/)?

博客已同步微信公众号:GIS茄子;若博客出现纰漏或有更多问题交流欢迎关注GIS茄子,或者邮箱联系(推荐-见主页). 00 前言 之前一段时间一直使用ENVI IDL处理遥感数据,但是确实对于一些比较新鲜的东西IDL并没有python那么好的及时性&…

【Linux】使用官方脚本自动安装 Docker(Ubuntu 22.04)

前言 Docker是一种开源平台,用于开发、交付和运行应用程序。它利用了容器化技术,使开发人员能够将应用程序及其依赖项打包到一个称为Docker容器的可移植容器中。这些容器可以在任何运行Docker的机器上快速、一致地运行,无论是开发环境、测试…

微服务架构之争:Quarkus VS Spring Boot

在容器时代(“Docker时代”),无论如何,Java仍然活着。Java在性能方面一直很有名,主要是因为代码和真实机器之间的抽象层,多平台的成本(一次编写,随处运行——还记得吗?&a…