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

news2024/11/16 9:23:40

本文将以解释计算二叉树的最小深度的思路为例,致力于用简洁易懂的语言详细描述普通二叉树和右倾斜二叉树在计算最小深度时的区别。通过跟随作者了解右倾斜二叉树的概念以及其最小深度计算过程,读者也将对左倾斜二叉树有更深入的了解。这将为解决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. 中序遍历的非递归实现:在二叉树的中序遍历中的左子树、根节点、右子树的顺序访问。

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FreeRTOS学习——同步互斥

FreeRTOS学习——同步互斥 目录 FreeRTOS学习——同步互斥一、概念1.1 同步1.2 互斥 二、示例——有缺陷的同步三、示例——优化有缺陷的同步四、示例——有缺陷的互斥五、总结 一、概念 1.1 同步 在FreeRTOS中,同步是指任务之间按照某种规则进行协调和按序执行的…

HarmonyOS:使用MindSpore Lite引擎进行模型推理

场景介绍 MindSpore Lite 是一款 AI 引擎,它提供了面向不同硬件设备 AI 模型推理的功能,目前已经在图像分类、目标识别、人脸识别、文字识别等应用中广泛使用。 本文介绍使用 MindSpore Lite 推理引擎进行模型推理的通用开发流程。 基本概念 在进行开…

PDI/Kettle-9.2.0.0-R(对应jdk1.8)源码编译问题记录及源码结构简介

目录 📚第一章 前言📗背景📗目的📗总体方向 📚第二章 代码结构初识基本结构📗代码模块详情 ⁉️问题记录❓问题一:代码分支哪些是发布版本❗答:后缀-R的版本 ❓问题二:50…

AI智能配音助手微信小程序前后端源码支持多种声音场景选择

大家好今天给大家带来一款配音小程序 ,这款小程序支持多种不同声音和场景的选择更人性化, 比如说支持各地区的方言,英文,童声呀等等、 另外也支持男声女声的选择,反正就是模板那些非常的多 当然啦音量,语调,语速那些都是可以DIY跳转的哟,所以说这一款小程…

使用PyTorch II的新特性加快LLM推理速度

Pytorch团队提出了一种纯粹通过PyTorch新特性在的自下而上的优化LLM方法,包括: Torch.compile: PyTorch模型的编译器 GPU量化:通过降低精度操作来加速模型 推测解码:使用一个小的“草稿”模型来加速llm来预测一个大的“目标”模型的输出 张量并行:通过在多个设备…

【专题】最小生成树(prim算法、kruscal算法)

目录 一、最小生成树二、Prim算法1. 算法思想2. 例题3. 性能分析 三、Kruscal算法1. 算法思想2. 例题3. 性能分析 一、最小生成树 生成树中边的权值(代价)之和最小的树。 二、Prim算法 1. 算法思想 设N(V,{E})是连通网,TE是N上最小生成树…

【IEEE】2区SCI,接收领域广,稳定检索47年!

重点 本期推荐 区块链是一种新兴技术,很多行业和领域都以创新方式采用了此技术,如能源、金融、媒体和娱乐以及零售等。此外,区块链作为一门新兴的交叉学科, 涉及密码学应用(加密,隐私等), 分布式…

stm32与Freertos入门(二)移植FreeRTOS到STM32中

简介 注意:FreeRTOS并不是实时操作系统,而是分时复用的,只不过切换频率很快,感觉上是同时在工作。本次使用的单片机型号为STM32F103C8T6,通过CubeMX快速移植。 一、CubeMX快速移植 1、选择芯片 打开CubeMX软件,进行…

Diva配置——Communication Tests

关联文章:CANoe.Diva生成测试用例 Diva目录 一、CANoe.Diva简介二、Communication Tests配置一、CANoe.Diva简介 CANoe.DiVa 是一种 CANoe 选项,用于对 ECU 中的诊断软件实施进行自动化测试。 可以通过CANdelaStudio制作的CDD或ODX文件,经过Diva配置自动生成测试用例和测试脚…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于时空注意力卷积模型的超短期风电功率预测》

这个标题描述了一种用于超短期风电功率预测的模型,该模型基于时空注意力卷积模型。下面我会逐步解读这个标题的关键词和背景: 超短期风电功率预测:风电功率预测是指根据历史风速和其他相关数据,通过建立数学模型来预测未来特定时间…

Vue学习计划-Vue2--VueCLi(四)组件传值和自定义事件

1. 组件传值 组件化编码流程: 拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用: 一个组件在用&#xff0c…

云演ctf 你能看到我吗?

1、看题目稍微尝试不好用,看到提示的文件访问也不好用。读取文件又好像拦截了啥。 读取hint.php文件payload ctfphp://filter/convert.base64-encode/resourcehihintnt.php2、解密后又看到一个文件 有需要绕过 ctfphp://filter/convert.base64-encode/resource..…

轻量封装WebGPU渲染系统示例<45>- 材质组装流水线(MaterialPipeline)灯光、阴影、雾(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/MaterialPipelineFog.ts 当前示例运行效果: 此示例基于此渲染系统实现,当前示例TypeScript源码如下: export class MaterialPipelineFog {pr…

C语言数组刷题-----数组填充

输入一个整数 V ,输出一个长度为 10 的数组 N ,数组中的第一个元素为 V ,每个后续元素的值都为上一个元素的值的 2 倍。 例如,如果输入整数为 1 ,则数组为:1,2,4,8… 输入格式 输入一个整数 V 。输出格…

cmake多模块架构, DLL依赖编译

整体结构: 最外层的cmakelist CMakeLists.txt project(cmakeMulPackage) cmake_minimum_required(VERSION 3.17) set(CMAKE_CXX_STANDARD 11)#设置环境相关 message("set env.cmake") message("CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}") …

TG-5510cb: txo高稳定性+105℃高温

TG-5510CB是一款高稳定性TCXO,可提供CMOS或限幅正弦输出,5G基站和边缘计算的额定温度为85C,需要室外安装、小型化和无风扇运行。与其他TCXO相比,实验室提供了许多改进,如低温度斜率和相位噪声。符合GR-1244-CORE地层3和…

详细教程 - 从零开发 Vue 鸿蒙harmonyOS应用 第一节

关于使用Vue开发鸿蒙应用的教程,我这篇之前的博客还不够完整和详细。那么这次我会尝试写一个更加完整和逐步的指南,从环境准备,到目录结构,再到关键代码讲解,以及调试和发布等,希望可以让大家详实地掌握这个过程。 一、准备工作 下载安装 DevEco Studio 下载地址:…

AD20-Excel创建IC类元件库

目录 准备模板AD操作 准备模板 AD操作 结果生成如下: over!!!

【教学类-06-18】20231216 (按“列”正序题)X-Y之间“加法题+题”(1页最多0-13。不考虑空格补全)

作品展示:按列排序,从小到大正序(有空格) 背景需求: 55格模板,很多幼儿都是按照“列”的方式,从上到下,从左向右完成题目的。 视觉上,两列之间间距大(给孩子…

labelme标注json文件检查标注标签(修改imageWidth,imagePath,imageHeight)

# !/usr/bin/env python # -*- encoding: utf-8 -*- #---wzhimport os import json# 这里写你自己的存放照片和json文件的路径 json_dir =rC:\Users\Lenovo\Desktop\json3 json_files = os.listdir(json_dir