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

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

3天内不再提示

Offer系列面试题0:重建二叉树

算法与数据结构 来源:图解面试算法 2020-07-09 15:03 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

今天分享的题目来源于 LeetCode 上的剑指 Offer 系列面试题07. 重建二叉树,近半年在微软面试环节出现过 2 次,属于中高难度的算法题!

一、题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历preorder=[3,9,20,15,7] 中序遍历inorder=[9,3,15,20,7]

返回如下的二叉树:

3 / 920 / 157

限制:

0 <= 节点个数 <= 5000

二、题目解析

首先,我们先来复习一下前序遍历、中序遍历。(在下方的视频中分布讲解)

前序遍历

二叉树的前序遍历顺序是:根节点、左子树、右子树,每个子树的遍历顺序同样满足前序遍历顺序。

中序遍历

二叉树的中序遍历顺序是:左子树、根节点、右子树,每个子树的遍历顺序同样满足中序遍历顺序。

复习过后,我们可以得出以下结论:

在二叉树的前序遍历序列中,第一个数字总是树的根结点的值;

在二叉树的中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边

以本题的序列为例,前序遍历序列的第一个数字 3 就是根结点的值,在中序遍历序列,找到根结点值的位置。根据中序遍历特点,在根结点的值 3前面的数字都是左子树结点的值,在根结点的值 3后面的数字都是右子树结点的值。

二叉树很重要的一个性质是递归,在找到了左子树、右子树的前序遍历序列和中序遍历序列后,我们可以按照同样的方法去确定子左子树和子右子树的构建。

具体的代码编写思路如下(来源于 Krahets's Blog):

递推参数:前序遍历中根节点的索引pre_root_idx、中序遍历左边界in_left_idx、中序遍历右边界in_right_idx。

终止条件:当in_left_idx > in_right_idx,子树中序遍历为空,说明已经越过叶子节点,此时返回 null 。

递推工作:

建立根节点 root :值为前序遍历中索引为pre_root_idx的节点值。

搜索根节点 root 在中序遍历的索引 i :为了提升搜索效率,本题解使用哈希表map预存储中序遍历的值与索引的映射关系,每次搜索的时间复杂度为 O(1)。

构建根节点root的左子树和右子树:通过调用 recursive()方法开启下一层递归。

左子树:根节点索引为 pre_root_idx + 1 ,中序遍历的左右边界分别为 in_left_idx 和 i - 1。

右子树:根节点索引为 i - in_left_idx + pre_root_idx + 1(即:根节点索引 + 左子树长度 + 1),中序遍历的左右边界分别为 i + 1 和 in_right_idx。

返回值:返回root,含义是当前递归层级建立的根节点root为上一递归层级的根节点的左或右子节点。

三、动画描述

四、图片描述

五、参考代码

classSolution{ //在中序序列中查找与前序序列首结点相同元素的时候,如果使用while循环去一个个找效率很慢 //这里我们借助数据结构HashMap来辅助查找,在开始递归之前把所有的中序序列的元素和它们所在的下标存到一个map中,这样查找的时间复杂度是O(logn) HashMapmap=newHashMap<>(); //保留的前序遍历 int[]preorder; publicTreeNodebuildTree(int[]preorder,int[]inorder){ this.preorder=preorder; //在开始递归之前把所有的中序序列的元素和它们所在的下标存到一个map中 for(inti=0;i< preorder.length; i++) {             map.put(inorder[i], i);         }         //二叉树的重要性质是递归         return recursive(0,0,inorder.length-1);     }     /** 根据前序遍历序列和中序遍历序列重新组建二叉树      * @param pre_root_idx 前序遍历的索引      * @param in_left_idx  中序遍历左边界的索引      * @param in_right_idx 中序遍历右边界的索引      */     public TreeNode recursive(int pre_root_idx, int in_left_idx, int in_right_idx) {         //子树中序遍历为空,说明已经越过叶子节点,此时返回 nul         if (in_left_idx >in_right_idx){ returnnull; } //root_idx是在前序里面的 TreeNoderoot=newTreeNode(preorder[pre_root_idx]); //通过map,根据前序的根节点的值,在中序中获取当前根的索引 intidx=map.get(preorder[pre_root_idx]); //左子树的根节点就是左子树的(前序遍历)第一个,就是+1,左边边界就是left,右边边界是中间区分的idx-1 root.left=recursive(pre_root_idx+1,in_left_idx,idx-1); //右子树的根,就是右子树(前序遍历)的第一个,就是当前根节点加上左子树的数量 root.right=recursive(pre_root_idx+(idx-1-in_left_idx+1)+1,idx+1,in_right_idx); returnroot; } }

这段代码的一个难点就是root.left与root.right,我这里抽离出来详细解释一下。

1、root.left

2、root.right

六、复杂度分析

时间复杂度

时间复杂度为 O(N)。

空间复杂度

空间复杂度为 O(N)。

七、相关标签

递归

哈希表

八、参考来源

1、https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/mian-shi-ti-07-zhong-jian-er-cha-shu-di-gui-fa-qin/ 题解区

2、https://krahets.gitee.io/views/sword-for-offer/2020-02-24-sword-for-offer-07.html

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

    关注

    1

    文章

    1701

    浏览量

    52616
  • 二叉树
    +关注

    关注

    0

    文章

    74

    浏览量

    12998

原文标题:面试字节跳动时,我竟然遇到了原题……

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    3DGS技术详解():视觉重建到物理仿真,3DGS如何走向工程应用?

    )如何突破静态重建的局限,实现对动态天气、移动光源等复杂环境因素的建模与仿真。这标志着3DGS已不再仅仅是“高保真场景重建工具
    的头像 发表于 03-20 17:37 917次阅读
    3DGS技术详解(<b class='flag-5'>二</b>):视觉<b class='flag-5'>重建</b>到物理仿真,3DGS如何走向工程应用?

    TCP三次握手与四次挥手的详细过程

    TCP 三次握手和四次挥手,大概是网络领域被问烂了的面试题。但真正能把状态变迁、序列号变化、抓包细节讲清楚的人并不多。很多人背了八股文,一到生产环境看 Wireshark 抓包就懵了
    的头像 发表于 02-25 10:38 428次阅读

    面试必看!排队自旋锁32位变量的域划分与核心作用

    在操作系统面试中,并发同步机制一直是高频考点,而排队自旋锁作为解决传统自旋锁“饥饿” 问题的关键技术,其 32 位变量的域划分更是面试官青睐的 “细节题”。不少同学能说出排队自旋锁的基本概念,却对其
    的头像 发表于 02-09 16:54 918次阅读
    <b class='flag-5'>面试</b>必看!排队自旋锁32位变量的域划分与核心作用

    入门宇机器人开发:从SDK源码探索到实战操作

    机器人(Unitree)作为全球领先的四足机器人研发企业,其推出的unitree_sdk2是面向旗下 Go2、H1、B2 等系列机器人的第代软件开发工具包。该 SDK 提供了丰富的接口和示例代码,支持开发者快速实现机器人控
    的头像 发表于 02-06 16:43 3373次阅读
    入门宇<b class='flag-5'>树</b>机器人开发:从SDK源码探索到实战操作

    亿纬锂能与杭集团达成战略合作

    近日,亿纬锂能与杭集团2025年战略研讨会暨战略合作协议签约仪式在杭州举行。亿纬锂能副总裁、商用车电池产品线总裁江吉兵博士,亿纬锂能商用车电池产品线国内销售部总经理井振江,杭集团董事、副总经理兼
    的头像 发表于 01-04 18:18 1180次阅读

    通过优化代码来提高MCU运行效率

    选择时间复杂度低的算法。 根据访问模式选择数据结构。频繁查找用哈希表,有序数据用二叉树等。 查表法:对于复杂的数学计算(如sin, log),或者协议解析,预先计算好结果存于数组中,用空间换时间
    发表于 11-12 08:21

    人工智能工程师高频面试题汇总:循环神经网络篇(题目+答案)

    后台私信雯雯老师,备注:循环神经网络,领取更多相关面试题随着人工智能技术的突飞猛进,AI工程师成为了众多求职者梦寐以求的职业。想要拿下这份工作,面试的时候得展示出你不仅技术过硬,还得能解决问题。所以
    的头像 发表于 10-17 16:36 853次阅读
    人工智能工程师高频<b class='flag-5'>面试题</b>汇总:循环神经网络篇(题目+答案)

    用30道电子工程师面试题来拷问堕落的你...

    今天用30道电子工程师面试题来拷问堕落的你,你能扛住第几题?1、下面是一些基本的数字电路知识问题,请简要回答之。(1)什么是Setup和Hold时间?答:Setup/HoldTime用于测试芯片
    的头像 发表于 10-15 17:37 1359次阅读
    用30道电子工程师<b class='flag-5'>面试题</b>来拷问堕落的你...

    请问rtt studio 的文件夹打红什么意思?

    rtt studio 的文件夹打红什么意思?而且文件夹里面实际是有文件的,但是浏览不出来。
    发表于 09-18 06:34

    亿纬锂能荣获杭集团2022-2024年度优秀供应商奖

    近日,亿纬锂能凭借卓越产品、可靠交付与优质服务荣获杭集团颁发的“2022-2024年度优秀供应商”奖。杭集团副总经理兼杭电器董事长金华曙、杭电器总经理兼杭博电机总经理李明辉出席
    的头像 发表于 07-15 09:00 1102次阅读

    每周推荐!硬件设计指南+无刷电机原理图大全+工程师面试题库汇总

    、硬件工程师或研发类笔试面试题库汇总 一、模拟电路(基本概念和知识总揽) 1、基本放大电路种类 (电压放大器,电流放大器,互导放大器和互阻放大器),优缺点,特别是广泛采用差分结构的原因。 2、负反馈种类
    发表于 07-07 14:38

    硬件工程师或研发类笔试面试题库汇总

    ,并具有电压跟随的特点。常用于电压放大电路的输入级和输出级,在功率放大电路中也常采用射极输出的形式。广泛采用差分结构的原因是差分结构可以抑制温度漂移现象。• 7、极管主要用于限幅,整流,钳位
    发表于 07-01 14:21

    最全的硬件工程师笔试试题

    硬件面试题之一 1、下面是一些基本的数字电路知识问题,请简要回答之。 (1) 什么是 Setup 和 Hold 时间? 答:Setup/Hold Time 用于测试芯片对输入信号和时钟信号之间的时间
    发表于 06-26 15:34

    【硬件方向】名企面试笔试真题:大疆创新校园招聘笔试题

    名企面试笔试真题:大疆创新校园招聘笔试题-硬件 是几年前的题目,不过值得参考一下哦 纯分享贴,有需要可以直接下载附件获取完整资料! (如果内容有帮助可以关注、点赞、评论支持一下哦~)
    发表于 05-16 17:31

    硬件工程师面试/笔试经典 100 题

    分享一些常见的硬件工程师面试/笔试题。公众号后台回复关键字:100题,可获取完整的PDF。--END--免责声明:本文转自网络,版权归原作者所有,如涉及作品版权问题,请及时与我们联系,谢谢!加入粉丝
    的头像 发表于 04-30 19:34 1658次阅读
    硬件工程师<b class='flag-5'>面试</b>/笔试经典 100 题