从中序与后序遍历序列构造二叉树

1.题目

这道题是2024-2-21的签到题,题目难度为中等。

考察知识点为递归。

题目链接:从中序与后序遍历序列构造二叉树

给定两个整数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

 

569ed4b46adc45fcab935fc61c3d75e4.png

 

2.思路

这道题其实思路和昨天题目差不多,如果没看过我昨天的题目解析的朋友可以参考下这个:

从前序与中序遍历序列构造二叉树

多余的废话我也就不多说了,下面是我这道题的核心思想:

 

构建递归函数

        首先是需要定义一个递归函数用于构建树,这里的树是针对所有具有树结构的,大至以root结点为根节点的整棵树,小至叶子节点这颗特殊的树(没有左右结点,其实结点可以看着一个特殊的子树),而构建树我们最需要确定的是它结点的中序遍历结果和后序遍历值,因此我们需要传入4个参数:

p_start:当前树的后序遍历开始索引

p_end:当前树的后序遍历结束索引

i_start:当前树的中序遍历开始索引

i_end:当前树的中序遍历结束索引

 

递归终止条件

        确定了递归函数的参数和意义后,我们需要确定递归终止条件,很明显,这个条件肯定和我们传入的参数有关,根据上面的4个参数我们可以知道一个树的遍历数组范围长度肯定是大于0的,而它的遍历数组长度由起始索引和终止索引决定,因此对于任意一个遍历数组,它的start必须小于end。于是我们可以定义递归终止条件是,当start > end,则返回None,否则则继续执行构建逻辑。

        如果满足上述条件,我们需要开始构建树的逻辑了,首先我们获取当前树的根节点值,这个我们可以从后序遍历数组和后序遍历结束索引来找,因为后序遍历数组的值肯定满足下面这个:

[(左子树的所有结点值)(右子树的所有结点值),根节点值]

        找到了根节点的值之后,我们利用python的index函数来找当前根节点值在当前的中序遍历数组索引值,从而得到当前树的左子结点数量和右子结点数量。

 

左右子树参数公式推导

        做完上述构建准备后,我们首先构建树的根节点,将当前树的root值传入类中并构建结点,然后递归构建它的左右子结点(其实可以看作是左右子树的两个根节点),两颗子树的4个构建参数肯定满足下面公式

左子树参数推导

eq?iStart_%7Bson%7D%20%3D%20iStart_%7Bparent%7D

eq?iEnd_%7Bson%7D%20%3D%20inoRootIndex%20-%201

eq?pStart_%7Bson%7D%20%3D%20pStart_%7Bparent%7D

eq?pStart_%7Bson%7D%20%3D%20pStart_%7Bparent%7D%20+%20leftNum%20-%201

 

右子树参数推导

eq?iStart_%7Bson%7D%20%3D%20inoRootIndex%20+%201

eq?iEnd_%7Bson%7D%20%3D%20iEnd_%7Bparent%7D

eq?pStart_%7Bson%7D%20%3D%20pStart_%7Bparent%7D%20+%20leftNum

eq?pEnd_%7Bson%7D%20%3D%20pEnd_%7Bparent%7D%20-%201

 

3.代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
        # 计算当前遍历数组的长度
        length = len(inorder)

        def build(i_start,i_end,p_start,p_end):
            # 如果开始坐标索引 > 结束坐标索引
            if i_start > i_end:
                return None
            # 根节点在中序遍历数组的下标索引
            ino_rootIndex = inorder.index(postorder[p_end])

            # 当前树的左子树所有结点个数
            leftNum = ino_rootIndex - i_start
            # 当前树的右子树所有结点个数
            rightNum = i_end - ino_rootIndex

            # 构建当前树的根节点
            root = TreeNode(postorder[p_end])
            # 递归构建当前树的左子树
            root.left = build(i_start,ino_rootIndex-1,p_start,p_start+leftNum-1)
            # 递归构建当前树的右子树
            root.right = build(ino_rootIndex+1,i_end,p_start+leftNum,p_end-1)
            # 返回当前树的根节点
            return root
        
        return build(0,length-1,0,length-1)


 

 

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

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

相关文章

(12)ATF BL31中断

欢迎关注“安全有理”微信公众号。 概述 系统在运行过程中的任何阶段,都有可能产生中断。在Armv8架构系统中,TEE-OS运行在安全世界的EL1,Rich-OS运行在非安全世界的EL1,而BL31则运行于EL3。想实现各种中断在三种状态下被处理的统…

QT day3 作业2.22

思维导图: 作业: 完善对话框,点击登录对话框,如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个Ok按钮,用户点击Ok后,关闭登录界面,跳转到…

JS前端高频面试

JS数据类型有哪些,区别是什么 js数据类型分为原始数据类型和引用数据类型。 原始数据类型包括:number,string,boolean,null,undefined,和es6新增的两种类型:bigint 和 symbol。&am…

2.22作业

test.c #include "test.h" seq_p creat_list(){seq_p L(seq_p)malloc(sizeof(seq_list));if(LNULL){printf("申请空间失败\n");return 0;}L->len0;return L; } int seq_p_empt(seq_p L){if(LNULL){return -12;}return L->len0?1:0; } int seq_p_fu…

PostgreSQL教程(二):pg安装、架构基础、创建并访问数据库

安装 自然,在你能开始使用PostgreSQL之前, 你必须安装它。PostgreSQL很有可能已经安装到你的节点上了, 因为它可能包含在你的操作系统的发布里, 或者是系统管理员已经安装了它。如果是这样的话, 那么你应该从操作系统…

BabylonJS 6.0文档 Deep Dive 动画(一):动画介绍

1. 动画介绍 无论动画如何实现,它都必须考虑所需的动作、时间、产生所需流动性所需的帧数以及序列中的关键点。这个介绍应该有助于理解Babylon.js是如何进行动画的,以及它们是如何实现的。 动画由一系列图像、帧生成,这些图像、帧一个接一个地…

Google插件Sider: ChatGPT Sidebar + GPTs GPT-4 Turbo Sider

Sider: ChatGPT Sidebar 可以使得满屏都是机器人,左侧栏可以打开访问GPT-4. 配置跳板机地址 google 搜索的右侧也有打开

MATLAB环境下基于短时傅里叶变换和Rényi熵的脑电信号和语音信号分析

傅里叶变换是不能很好的反映信号在时域的某一个局部范围的频谱特点的,这一点很可惜。因为在许多实际工程中,人们对信号在局部区域的特征是比较关心的,这些特征包含着十分有用的信息。这类信号因为在时域(或者是空间域)上具有突变的非稳定性和…

C语言自定义类型:结构体的使用及其内存对齐【超详细建议点赞收藏】

目录 1. 结构体类型的声明1.1 结构的声明1.2 结构体变量的创建和初始化1.3 结构的特殊声明---匿名结构体1.4 结构的自引用 2.结构体内存对齐(重点!!)2.1 对齐规则2.2 例题讲解2.3 为什么存在内存对齐?2.4 修改默认对齐…

华为全新研发中心即将启用,投资超百亿 | 百能云芯

2月19日 ,上海市发改委网站发布了《2024年上海市重大工程清单》,内容涉及科技产业、社会民生、生态文明建设、城市基础设施、城乡融合与乡村振兴等五大类,共191项重大工程。 191项重大工程中,科技产业类占比最多(76项&…

Spring Boot打war包部署到Tomcat,访问页面404 !!!

水善利万物而不争,处众人之所恶,故几于道💦 文章目录 Spring Boot打war包部署到Tomcat,访问页面404 !!!解决办法:检查Tomcat版本和Jdk的对应关系,我的Tomcat是6.x&#x…

RK3568平台开发系列讲解(Linux系统篇)通过I2C总线访问客户端方法

🚀返回专栏总目录 文章目录 一、普通I2C通信二、系统管理总线(SMBus)兼容函数三、在开发板配置文件中实例化I2C设备(弃用的旧方式)沉淀、分享、成长,让自己和他人都能有所收获!😄 串行总线事务只是访问寄存器来设置/获取其内容。I2C遵循该规则。I2C内核提供两种API,…

(十二)【Jmeter】线程(Threads(Users))之setUp 线程组

简述 操作路径如下: 作用:在正式测试开始前执行预加载或预热操作,为测试做准备。配置:设置预加载或预热操作的采样器、循环次数等参数。使用场景:确保在正式测试开始前应用程序已经达到稳定状态,减少测试结果的偏差。优点:提供预加载或预热操作,确保测试的准确性。缺…

Code Control Process

代码提交流程(Code Control Process) VSS,早前定义的版本控制,没有谁对不对,但是要根本解决冲突,特别人多的时候,50个人的时候,处理冲突时非常的麻烦的,改半天还改错了&…

C++模板从入门到入土

1. 泛型编程 如果我们需要实现一个不同类型的交换函数,如果是学的C语言,你要交换哪些类型,不同的类型就需要重新写一个来实现,所以这是很麻烦的,虽然可以cv一下,有了模板就可以减轻负担。 下面写一个适…

重新安装VSCode后,按住Ctrl(or Command) 点击鼠标左键不跳转问题

重新安装VSCode后,按住Ctrl(or Command) 点击鼠标左键不跳转问题 原因:重新安装一般是因为相应编程语言的插件被删除了或还没有下载。 本次是由于Python相关的插件被删除了,因此导致Python无法跳转。 解决办法 在vs…

人工智能会是第四次工业革命吗?引领第四次工业革命的核心力量

许多专家和学者确实认为人工智能(AI)将是第四次工业革命的核心。第四次工业革命,也被称为"工业4.0",是指正在发生的一场以高度数字化和互联网为基础的技术革新。 自18世纪的蒸汽机,到20世纪的电力和信息技术…

YOLO-World初体验:Ultralytics版本,可直接上手,离线运行

YOLOv8官方新增了对YOLO-World的支持,本文利用其提供的模型及接口进行了体验。 关于YOLO-World的详细介绍,见:YOLO-World:实时开放词汇目标检测-CSDN博客 目录 1. 前言 2. 安装(更新) Ultralytics安装&am…

低代码开发:拖拉拽自定义表单的创新之道

一、前言 在软工圣经《人月神话》一书中,作者Brooks指出了软件发展的一个僵局:在落后的项目中增加人手,只会使进度更加落后。 为了更快完成项目,开发团队会发展的极其庞大,以致于所有的时间都花费在沟通和变更决策上&a…

Apache服务

目录 引言 一、常见的http服务程序 (一)lls (二)nginx (三)Apache (四)Tomcat 二、Apache特点 三、Apache服务的安装 (一)yum安装及配置文件 1.配置…