(树) 剑指 Offer 07. 重建二叉树 ——【Leetcode每日一题】
❓剑指 Offer 07. 重建二叉树
难度:中等
输入某二叉树的 前序遍历 和 中序遍历 的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
示例 1:

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]
限制:
- 0 <= 节点个数 <= 5000
注意:本题与 105. 从前序与中序遍历序列构造二叉树 相同。
💡思路:递归
二叉树前序遍历的顺序为:
- 先遍历根节点;
- 随后递归地遍历左子树
- 最后递归地遍历右子树
二叉树中序遍历的顺序为:
- 先递归地遍历左子树;
- 随后遍历根节点;
- 最后递归地遍历右子树
在「递归」地遍历某个子树的过程中,我们也是将这颗子树看成一颗全新的树,按照上述的顺序进行遍历。挖掘「前序遍历」和「中序遍历」的性质,我们就可以得出本题的做法。
前序遍历的第一个值为根节点的值,使用这个值将 中序遍历 结果分成两部分:
左部分为树的左子树中序遍历结果;右部分为树的右子树中序遍历的结果;- 然后分别对左右子树递归地求解。

只要我们在中序遍历中定位到根节点,那么我们就可以分别知道左子树和右子树中的节点数目。
- 由于同一颗子树的 前序遍历 和 中序遍历 的
长度显然是相同的,因此我们就可以对应到前序遍历的结果中,对上述形式中的所有左右括号进行定位。 - 这样以来,我们就知道了左子树的前序遍历和中序遍历结果,以及右子树的前序遍历和中序遍历结果,我们就可以递归地对构造出左子树和右子树,再将这两颗子树接到根节点的左右位置。
🍁代码:(C++、Java)
C++
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
private:unordered_map<int, int> index;//缓存中序遍历数组每个值对应的索引TreeNode* myBuildTree(const vector<int> preorder, int preL, int preR, int inL){if(preL > preR) return nullptr;// 前序遍历中的第一个节点就是根节点TreeNode* root = new TreeNode(preorder[preL]);// 在中序遍历中定位根节点int idx = index[root->val];// 得到左子树中的节点数目int len = idx - inL;root->left = myBuildTree(preorder, preL + 1, preL + len, inL);root->right = myBuildTree(preorder, preL + len + 1, preR, inL + len + 1);return root;}public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {for(int i = 0; i < preorder.size(); i++){index[inorder[i]] = i;}return myBuildTree(preorder, 0, preorder.size() - 1, 0);}
};
Java
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val = x; }* }*/
class Solution {private Map<Integer, Integer> index = new HashMap<>();//缓存中序遍历数组每个值对应的索引public TreeNode buildTree(int[] preorder, int[] inorder) {for (int i = 0; i < preorder.length; i++){index.put(inorder[i], i);}return myBuildTree(preorder, 0, preorder.length - 1, 0);}private TreeNode myBuildTree(int[] preorder, int preL, int preR, int inL){if(preL > preR) return null;// 前序遍历中的第一个节点就是根节点TreeNode root = new TreeNode(preorder[preL]);// 在中序遍历中定位根节点int idx = index.get(root.val);// 得到左子树中的节点数目int len = idx - inL;root.left = myBuildTree(preorder, preL + 1, preL + len, inL);root.right = myBuildTree(preorder, preL + len + 1, preR, inL + len + 1);return root;}
}
🚀 运行结果:

🕔 复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n),其中
n是树中的节点个数。 - 空间复杂度: O ( n ) O(n) O(n),除去返回的答案需要的 O ( n ) O(n) O(n) 空间之外,我们还需要使用 O ( n ) O(n) O(n) 的空间存储哈希映射,以及 O ( h ) O(h) O(h)(其中
h是树的高度)的空间表示递归时栈空间。这里h < n,所以总空间复杂度为 O ( n ) O(n) O(n)。
题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!
注: 如有不足,欢迎指正!
相关文章:
(树) 剑指 Offer 07. 重建二叉树 ——【Leetcode每日一题】
❓剑指 Offer 07. 重建二叉树 难度:中等 输入某二叉树的 前序遍历 和 中序遍历 的结果,请构建该二叉树并返回其根节点。 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 示例 1: Input: preorder [3,9,20,15,7], inorder [9,3,15,20,7] …...
Gitlab 合并分支与请求合并
合并分支 方式一:图形界面 使用 GitGUI,右键菜单“GitExt Browse” - 菜单“命令” - 合并分支 方式二:命令行 在项目根目录下打开控制台,注意是本地 dev 与远程 master 的合并 // 1.查看本地分支,确认当前分支是否…...
【Matter】基于Ubuntu 22.04 编译chip-tool工具
前言 编译过程有点曲折,做下记录,过程中,有参考别人写的博客,也看github 官方介绍,终于跑通了~ 环境说明: 首先需要稳定的梯子,可以访问“外网”ubuntu 环境,最终成功实验在Ubunt…...
将 MongoDB 的 List<Document> 转换为对象列表
当我们使用 MongoDB 存储数据时,经常会涉及到将 MongoDB 的文档对象转换为对象列表的需求。在 Java 中,我们可以使用 MongoDB 的 Java 驱动程序和自定义类来实现这一转换过程。 本篇博客将介绍如何将 MongoDB 中的 List<Document> 转换为对象列表。…...
【Linux下6818开发板(ARM)】SecureCRT串口和交叉编译工具(巨细版!)
(꒪ꇴ꒪ ),hello我是祐言博客主页:C语言基础,Linux基础,软件配置领域博主🌍快上🚘,一起学习!送给读者的一句鸡汤🤔:集中起来的意志可以击穿顽石!作者水平很有限,如果发现错误&#x…...
应届生如何快速找Java开发工程师,先学会这17个基础问题
一、Java 基础 JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境。 JRE:Java Runtime Environment 的简称,java 运行环境,为 java 的…...
数学建模学习(5):数学建模各类题型及解题方案
一、数学建模常见的题型 总体来说,数学建模赛题类型主要分为:评价类、预测类和优化类三种,其中优化类是最常见的赛题类 型,几乎每年的地区赛或国赛美赛等均有出题,必须要掌握并且熟悉。 二、评价类赛题 综合评价是数学…...
【学习笔记】视频检测方法调研
目录 1 引言2 方法2.1 视频目标跟踪2.1.1 生成式模型方法2.1.2 判别式模型方法2.1.2.1 基于相关滤波跟踪2.1.2.2 基于深度学习跟踪 2.2 视频异常检测2.2.1 基于重构方法2.2.2 基于预测方法2.2.3 基于分类方法2.2.4 基于回归方法 2.3 深度伪造人脸视频检测2.3.1 基于RNN时空融合…...
idea terminal npm指令无效
文章目录 一、修改setting二、修改启动方式 一、修改setting 菜单栏:File->Settings 二、修改启动方式 快捷方式->右键属性->兼容性->勾选管理员身份运行...
低代码开发平台源码
什么是低代码开发平台? 低代码来源于英文“Low Code,它意指一种快速开发的方式,使用最少的代码、以最快的速度来交付应用程序。通俗的来说,就是所需代码数量低,开发人员门槛低,操作难度低。一般采用简单的图…...
【UE5 多人联机教程】04-加入游戏
效果 步骤 1. 新建一个控件蓝图,父类为“USC_Button_Standard” 控件蓝图命名为“UMG_Item_Room”,用于表示每一个搜索到的房间的界面 打开“UMG_Item_Room”,在图表中新建一个变量,命名为“Session” 变量类型为“蓝图会话结果…...
自然语言处理从入门到应用——LangChain:模型(Models)-[大型语言模型(LLMs):缓存LLM的调用结果]
分类目录:《自然语言处理从入门到应用》总目录 from langchain.llms import OpenAI在内存中缓存 import langchain from langchain.cache import InMemoryCachelangchain.llm_cache InMemoryCache()# To make the caching really obvious, lets use a slower mode…...
Python 算法基础篇之图的遍历算法:深度优先搜索和广度优先搜索
Python 算法基础篇之图的遍历算法:深度优先搜索和广度优先搜索 引言 1. 图的遍历概述2. 深度优先搜索( DFS )2.1 DFS 的实现2.2 DFS 的应用场景 3. 广度优先搜索( BFS )3.1 BFS 的实现3.2 BFS 的应用场景 4. 示例与实例…...
文本缩略 文本超出显示省略号 控制超出省略的行数
文本缩略 .abb{//超出一行省略overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }超出2行省略 .abb2{display: -webkit-box !important;-webkit-box-orient: vertical;//超出2行省略-webkit-line-clamp:2;overflow: hidden; }控制超出省略的行数 .txt-over{/*控…...
云原生架构
1. 何为云原生? 很多IT业内小伙伴会经常听到这个名词,那么什么是云原生呢?云原生是在云计算环境中构建、部署和管理现代应用程序的软件方法。 当今时代,众多企业希望构建高度可扩展、灵活且有弹性的应用程序,以便能够快…...
Java 生成随机数据
文章目录 1. Java-faker依赖demo 2. common-random依赖demo 1. Java-faker 依赖 <dependency><groupId>com.github.javafaker</groupId><artifactId>javafaker</artifactId><version>1.0.2</version> </dependency>https://…...
基于OpenCV的红绿灯识别
基于OpenCV的红绿灯识别 技术背景 为了实现轻舟航天机器人实现红绿灯的识别,决定采用传统算法OpenCV视觉技术。 技术介绍 航天机器人的红绿灯识别主要基于传统计算机视觉技术,利用OpenCV算法对视频流进行处理,以获取红绿灯的状态信息。具…...
JavaScript快速入门:ComPDFKit PDF SDK 快速构建 Web端 PDF阅读器
JavaScript快速入门:ComPDFKit PDF SDK 快速构建 Web端 PDF阅读器 在当今丰富的网络环境中,处理 PDF 文档已成为企业和开发人员的必需品。ComPDFKit 是一款支持 Web 平台并且功能强大的 PDF SDK,开发人员可以利用它创建 PDF 查看器和编辑器&…...
Flutter 网络请求
在Flutter 中常见的网络请求方式有三种:HttpClient、http库、dio库; 本文简单介绍 使用dio库使用。 选择dio库的原因: dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载…...
吃透《西瓜书》第三章 线性模型:多元线性回归
🍉 吃瓜系列 教材:《机器学习》 周志华著 🕒时间:2023/7/26 目录 一、多元线性回归 1 向量化 1.1.1 向量化 1.1.2 使用最小二乘法构建损失函数 1.1.3 去除求和符号,改成向量点乘的形式 1.1.4 数学原理 2 求解…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
