​面试经典150题——从前序与中序遍历序列构造二叉树

aerial photo of mountain range

1. 题目描述

image-20240417152807018

2.  题目分析与解析

二叉树的前序、中序和后序遍历

二叉树的前序、中序和后序遍历是树的三种基本遍历方式,它们是通过不同的顺序来访问树中的节点的。

  1. 前序遍历(Pre-order traversal)

    • 访问根节点

    • 前序遍历左子树

    • 前序遍历右子树

  2. 中序遍历(In-order traversal)

    • 中序遍历左子树

    • 访问根节点

    • 中序遍历右子树

  3. 后序遍历(Post-order traversal)

    • 后序遍历左子树

    • 后序遍历右子树

    • 访问根节点

每种遍历方式都有其特定的应用场景,以及在不同问题中的实用性。

  • 前序遍历常用于复制二叉树、计算表达式树的值等。

  • 中序遍历常用于搜索树(如二叉搜索树)中,可以按照从小到大的顺序访问所有节点。

  • 后序遍历通常用于释放二叉树的内存空间。

根据题目要求,我们可以从以下几个方面着手:

  1. 理解二叉树的性质

    通过这些性质,根节点在前序遍历中是容易找到的,而中序遍历中根节点的位置可以用来划分左子树和右子树。

    • 前序遍历(Preorder Traversal)的特点是根节点首先出现,接着是左子树的所有节点,最后是右子树的所有节点。

    • 中序遍历(Inorder Traversal)的特点是先遍历左子树,然后是根节点,最后是右子树。

  2. 使用哈希映射优化搜索

    • 而在中序遍历中频繁查找节点位置是一个时间复杂度较高的操作(O(n)),为了提升效率,可以使用哈希映射(HashMap)存储每个值与其在中序遍历中的索引。这样,节点位置的查找时间复杂度可以降低到O(1)。

    • 因为题目中提到了:

      image-20240418102452315

  3. 递归构建二叉树

    为什么使用递归求解?因为构建一棵二叉树无非就是三个步骤:创建根节点,构建左子树,构建右子树。因此这个问题就可以按照如下求解:

    但是注意递归求解肯定有返回条件,这个返回条件就是左边界大于右边界,也就是子树节点个数小于等于0的时候代表没有左子树了,返回null。所以有如下:

    • 递归基:如果前序遍历的子区间为空(即左边界大于右边界),这意味着没有子树可以构建,返回null

    • 创建根节点:前序遍历的第一个节点总是根节点,使用这个性质创建当前的根节点。

    • 计算左子树的大小:根据根节点在中序遍历中的位置和左边界的差值,可以确定左子树的节点数目。

    • 递归构建左子树:在前序遍历中,紧接根节点之后的一段连续序列对应于左子树的前序遍历,而在中序遍历中,根节点位置之前的一段序列对应于左子树的中序遍历。利用这两个序列,递归构建左子树。

    • 递归构建右子树:类似地,根据前序和中序遍历中左子树节点数的信息,可以确定右子树的前序和中序遍历序列,进而递归构建右子树。

    1. 构建根节点

    2. 找到左子树的部分构建左子树

    3. 找到右子树的部分构建右子树

    4. 返回根节点

3. 代码实现

image-20240418101734360

image-20240418101615273

4. 相关复杂度分析

时间复杂度

  1. 哈希映射构建

    • 遍历中序数组以构建哈希映射,时间复杂度为 (O(n)),其中 (n) 是树中节点的数量。

  2. 递归构建二叉树

    • 每次递归调用处理一个节点(根节点),因此每个节点会被访问一次。

    • 虽然递归多次,但每个节点仅在其对应的递归层次中处理一次,因此总的时间复杂度为 (O(n))。

总的时间复杂度:由于哈希映射的构建和递归构建树各占 (O(n)),总时间复杂度是 (O(n))。

空间复杂度

  1. 哈希映射

    • 哈希映射存储所有节点及其在中序遍历中的索引,占用 (O(n)) 的空间。

  2. 递归调用栈

    • 最坏情况下,二叉树是高度不平衡的,例如全部倾斜成一条直线,这时递归的深度为 (n),因此调用栈的最大深度也为 (O(n))。

    • 如果树是平衡的,递归的深度大约是 (log n)。

  3. 递归中的临时变量

    • 在每次递归调用中,使用了一些额外的空间来存储诸如 preorder_left, preorder_right, inorder_left, inorder_right, inorder_root_indexleft_tree_size 等变量,但这些都是常数空间,因此不影响总体空间复杂度。

总的空间复杂度:最坏情况下为 (O(n)),主要由于哈希映射和递归栈的空间需求。

结论

代码的时间复杂度为 (O(n)) 且空间复杂度为 (O(n))。这确保了算法在处理大规模数据时的效率和可行性,同时空间复杂度主要受递归深度和哈希映射的存储需求影响。这是构建二叉树时的典型性能表现,特别是当给定两种遍历结果时。

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

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

相关文章

Linux-Stunnel介绍

1、定义 Stunnel是一个自由的跨平台软件,用于提供全局的TLS/SSL服务。针对本身无法进行TLS或SSL通信的客户端及服务器,Stunnel可提供安全的加密连接。该软件可在许多操作系统下运行,包括Unix-like系统,以及Windows。Stunnel依赖于…

15、ESP32 BLE

低功耗蓝牙: 低功耗蓝牙,简称 BLE,是蓝牙的省电版本。BLE 的主要应用是短距离传输少量数据(低带宽)。与经典蓝牙不同,BLE 始终保持睡眠模式,除非启动连接,这使得它消耗的功率非常低。…

智能设备订购如何使药品供应链受益

自从 Covid-19 大流行扰乱全球供应链以来,制药行业对增强弹性的需求变得比以往任何时候都更加重要。药品供应链已经开始数字化转型,采用新技术有助于确保药品和关键物资按时到达目的地并支持长期业务战略。其中一种解决方案是在移动设备上进行智能设备订…

在 Ubuntu 12.10 安装 wxPython

安装 wxPython 可以使用 pip 工具,但在 Ubuntu 12.10 上需要首先安装 wxPython 的依赖项。请注意,Ubuntu 12.10 已于2013年终止支持,建议升级到更高版本的 Ubuntu。以下是在 Ubuntu 12.10 上安装 wxPython 的一般步骤: 一、问题背…

HTML学习笔记:(二)框架实例

2、 框架实例 注意&#xff1a;frameset不能和body标签共存 <frameset>元素是用于创建框架页面的&#xff0c;它允许在一个浏览器窗口中显示多个HTML页面。然而&#xff0c;<frameset>是一种较旧的方式来构建网页&#xff0c;它不符合现代Web标准&#xff08;比如…

【VTKExamples::Meshes】第 十四期 ExtractEdges

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例ExtractEdges,并解析接口vtkExtractEdges,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~…

深入理解JAVA垃圾收集器CMS,G1工作流程原理 GC流程图 什么社会触发Minor GC?触发MinorGC过程。Full GC 过程。

java CMS&#xff0c;G1垃圾收集器工作流程原理浅析 JVM内存空间基础知识点&#xff08;基于JDk1.8&#xff09; 1.方法区&#xff1a;逻辑概念&#xff0c;元空间&#xff0c;方法区主要用于存储类的信息、常量池、方法数据、方法代码等。方法区逻辑上属于堆的一部分&#xf…

Github 2024-04-15 开源项目日报Top10

根据Github Trendings的统计,今日(2024-04-15统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目4TypeScript项目2HTML项目1JavaScript项目1C++项目1Rust项目1Mojo项目1Fooocus: 图像生成软件 创建周期:188 天开发语言:Python协议…

Mathtype用法记录

常用写法 公式编号 给公式插入编号的方法 手动修改公式编号为指定值 例如编号(8.3.1)修改为(8.3.7)&#xff0c;即章、节号不变&#xff0c;公式序号改为7。 可修改编号的域代码&#xff0c;比如(8.3.1)的域代码为&#xff1a; { { MACROBUTTON MTPlaceRef \* MERGEFORMAT…

【星瑞格】SinoDB国产数据库安装初体验及学习指南

今天和大家一起来看看一款来自福建的国产数据库——SinoDB。本人很早就听说过这款数据库&#xff0c;而且星瑞格公司就在同一栋办公楼。虽然以前就已经对这颗国产数据库有一定的了解&#xff0c;并没有真正的去使用一把。随着数据库国产化改造工作的推进&#xff0c;身边的客户…

使用docker配置CCM-SLAM

一.Docker环境配置 1.拉取Docker镜像 sudo docker pull ubuntu:18.04拉取的为ununtu18版本镜像&#xff0c;环境十分干净&#xff0c;可以通过以下命令查看容器列表 sudo docker images 如果想删除多余的docker image&#xff0c;可以使用指令 sudo docker rmi -f <id&g…

基于Java+SpringBoot+Vue前后端分离仓库管理系统

基于JavaSpringBootVue前后端分离仓库管理系统 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#…

《QT实用小工具·三十二》九宫格炫酷主界面

1、概述 源码放在文章末尾 项目实现了九宫格炫酷主界面&#xff0c;下面是项目demo演示&#xff1a; 项目部分代码如下&#xff1a; #pragma execution_character_set("utf-8")#include "frmmain.h" #include "ui_frmmain.h"frmMain::frmMain…

Android Studio学习笔记——广播机制Broadcast

Android Studio学习笔记——广播机制 5.1 广播机制简介5.2 接收系统广播5.2.1 动态注册监听网络变化5.2.2 静态注册实现开机启动 5.3 发送自定义广播5.3.1 发送标准广播5.3.2 发送有序广播 5.4 使用本地广播5.5 广播的最佳实践——强制下线功能 5.1 广播机制简介 安卓每个应用…

百度网盘超级会员2024最新白嫖30天教程

百度网盘超级会员服务是百度网盘提供的一项高级服务&#xff0c;它为用户提供了许多特权和功能&#xff0c;旨在为用户带来更加便捷、高效的文件存储和管理体验。以下是关于百度网盘超级会员服务的详细介绍&#xff1a; 百度网盘VIP领取入口&#xff1a; 关注公众号回复&#x…

在Linux操作系统中,修改文件目录权限常用的命令操作

修改文件的属主或者是属组 命令chown 用户名.用户组名&#xff0c;文件路径 如上图所示&#xff0c;使用命令 chown martin.caiwu /opt/test/1.txt 将文件1.txt的属主修改为martin 。 将文件1.txt的属组修改为caiwu 如上图所示&#xff0c;使用命令chown .jishu /opt/test/…

【muduo源码学习】one-loop-per-thread核心原理

在 TCP 网络编程中&#xff0c;这里我们特指在单机的环境下&#xff0c;主要关注两件事。第一&#xff0c;如何正确的处理TCP的连接和断开&#xff0c;以及正确处理数据的收发&#xff1b;在错综复杂的网络环境中&#xff0c;这并非易事&#xff0c;涉及很多细节。第二&#xf…

过滤器和拦截器的样例

拦截器实例代码&#xff0c;加上之后必须登录才能访问其他功能接口 package com.itheima.interceptors;import com.itheima.utils.JwtUtil; import com.itheima.utils.ThreadLocalUtil; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSer…

数据结构和算法:贪心

贪心算法 贪心算法是一种常见的解决优化问题的算法&#xff0c;其基本思想是在问题的每个决策阶段&#xff0c;都选择当前看起来最优的选择&#xff0c;即贪心地做出局部最优的决策&#xff0c;以期获得全局最优解。 贪心算法和动态规划都常用于解决优化问题。它们之间存在一…

screen常用命令

screen是一个在Linux系统中常用的命令行终端模拟器&#xff0c;它允许用户在一个单一终端会话中管理多个终端窗口。以下是一些常用的screen命令 1、创建一个新的screen会话并命名 screen -S <name>2、control a d &#xff1a;分离&#xff08;detach&#xff09;当前的…