根据一棵树的两种遍历构造二叉树

题目

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

示例 1:

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

示例 2:

输入: preorder = [-1], inorder = [-1]
输出: [-1]

提示:

  • 1 <= preorder.length <= 3000
  • inorder.length == preorder.length
  • -3000 <= preorder[i], inorder[i] <= 3000
  • preorder 和 inorder 均 无重复 元素
  • inorder 均出现在 preorder
  • preorder 保证 为二叉树的前序遍历序列
  • inorder 保证 为二叉树的中序遍历序列

前置知识: 

preorder :前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点--->根的左子树--->根的右子树。

inorder:中序遍历(Inorder Traversal)——根的左子树--->根节点--->根的右子树

前序遍历所得的第一个节点就是根节点,所以可以用来确定的是root根节点在中序遍历的位置,

再根据中序遍历,root根节点的左边是这棵二叉树的左树,root根节点的右边是这课二叉树的右树来构建这课二叉树

以示例1为例谈谈对题目的理解

示例1输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

preorder = [  3,  9,  20,  15,  7  ]   3就为这棵二叉树的root根节点

inorder = [  9,  315,  20,  7  ]  9为root的左树,并且只有一个节点,所以9为root的左节点

15,20,7这三个节点为root的右树,再根据中序遍历根的左子树--->根节点--->根的右子树可得

root的右节点为20这个节点,20节点的左节点为15这个节点,右节点为7这个节点

画图演示上述文字说明


解题思路:

根据题目所给的前序遍历的节点顺序在中序遍历中进行递归来构建二叉树

1.根据前序遍历找到中序遍历根节点iRoot的位置,创建根节点,再确定iBegin,iEnd的位置,i++;

2.对iBegin和iEnd的位置进行判断,当iBegin>iEnd时,返回null,递归开始回退;

2.在中序遍历当中,根据iRoot ,iBegin,iEnd的位置,并进行左树和右树的构建;

对上述三步进行递归,递归完了之后,二叉树构建完成,返回根节点root

注:对前序遍历所得节点的利用才是本题代码的灵魂所在

图示:


解题代码

class Solution {
    public int i = 0;

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return create_a_binary_tree(preorder, inorder, 0, inorder.length - 1);
    }

    public TreeNode create_a_binary_tree(int[] preorder, int[] inorder, int inBegin, int inEnd) {
        if (inBegin > inEnd) {
            return null;
            //给定的数组int[] preorder, int[] inorder,遍历完了,没有子树了,该节点为空节点,返回null,递归开始回退
        }
        //先根据先序遍历创建根节点
        TreeNode root = new TreeNode(preorder[i]);
        //找到当前根节点,在中序遍历的位置
        int rootIndex = findIndex(inorder, inBegin, inEnd, preorder[i]);
        i++;
        //递归构建左树
        root.left = create_a_binary_tree(preorder, inorder, inBegin, rootIndex - 1);
        //递归构建右树
        root.right = create_a_binary_tree(preorder, inorder, rootIndex + 1, inEnd);
        //前序遍历完成,返回根节点
        return root;
    }

    private int findIndex(int[] inorder, int inBegin, int inEnd, int key) {
        for (int j = inBegin; j <= inEnd; j++) {
            if (inorder[j] == key) {
                return j;
            }
        }
        return -1;
    }
}

运行结果

题目链接

https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/submissions/

举一翻三,再来一道

根据一棵树的中序遍历与后序遍历构造二叉树

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

示例 1:

输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]

示例 2:

输入:inorder = [-1], postorder = [-1]
输出:[-1]

后序遍历(Postorder Traversal)——根的左子树--->根的右子树--->根节点。
创建根节点后,先创建右数,再创建左树

根据示例1进行讲解,下图是代码递归过程

随着代码的递归,二叉树随之构建的过程 

 解题代码

public class Solution {
    public int i = 0;

    public TreeNode buildTree(int[] inorder, int[] postorder) {
        i = postorder.length - 1;
        return create_a_binary_tree(postorder, inorder, 0, inorder.length - 1);
    }

    public TreeNode create_a_binary_tree(int[] postorder, int[] inorder, int inBegin, int inEnd) {
        if (inBegin > inEnd) {
            return null;
            //给定的数组int[] postorder, int[] inorder,遍历完了,没有子树了,该节点为空节点,返回null,递归开始回退
        }
        //先根据先序遍历创建根节点
        TreeNode root = new TreeNode(postorder[i]);
        //找到当前根节点,在中序遍历的位置
        int rootIndex = findIndex(inorder, inBegin, inEnd, postorder[i]);
        i--;
        //递归先构建右树
        root.right = create_a_binary_tree(postorder, inorder, rootIndex + 1, inEnd);
        //递归后构建左树
        root.left = create_a_binary_tree(postorder, inorder, inBegin, rootIndex - 1);
        //前序遍历完成,返回根节点
        return root;
    }

    private int findIndex(int[] inorder, int inBegin, int inEnd, int key) {
        for (int j = inBegin; j <= inEnd; j++) {
            if (inorder[j] == key) {
                return j;
            }
        }
        return -1;
    }
}

运行结果

题目链接:

https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/submissions/

完结撒花✿✿ヽ(°▽°)ノ✿✿

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

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

相关文章

sql server安装报错 合成活动模板库(ATL) 失败

错误 “合成活动模板库(ATL) 规则失败“ 解决办法&#xff1a; 进入SQL Server 2008R2安装包目录找到文件&#xff1a;sqlsupport_msi&#xff0c;安装此文件之后&#xff0c;再安装SQL Server&#xff0c;便可解决该问题。C:\SQL Server 2008R2\new\SQL Server 2008R2\2052_CH…

uniapp开发微信小程序使用painter将页面转换为图片并保存到本地相册

引言 我使用到painter的原因是&#xff0c;在uniapp开发微信小程序时&#xff0c;需要将一个页面的内容转换成图片保存到本地相册。 起初在网上找到很多都是在uniapp中使用 html2canvas 将网页转换成图片再jspdf将图片转换为pdf&#xff0c;但是这种方式在小程序环境不支持&am…

【数据结构】二叉树链式结构的实现及其常见操作

目录 1.手搓二叉树 2.二叉树的遍历 2.1前序、中序以及后序遍历 2.2二叉树的层序遍历 3.二叉树的常见操作 3.1求二叉树节点数量 3.2求二叉树叶子节点数量 3.3求二叉树第k层节点个数 3.3求二叉树的深度 3.4二叉树查找值为x的节点 4.二叉树的销毁 1.手搓二叉树 在学习…

[数据集][目标检测]钢材表面缺陷目标检测数据集VOC格式2279张10类别

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;2279 标注数量(xml文件个数)&#xff1a;2279 标注类别数&#xff1a;10 标注类别名称:["yueyawan",&…

ceph数据分布

ceph的存储是无主结构&#xff0c;数据分布依赖client来计算&#xff0c;有两个条主要路径。 1、数据到PG 2、PG 到OSD 有两个假设&#xff1a; 第一&#xff0c;pg的数量稳定&#xff0c;可以认为保持不变&#xff1b; 第二&#xff0c; OSD的数量可以增减&#xff0c;OSD的…

【TI-CCS笔记】工程编译配置 bin文件的编译和生成 各种架构的Post-build配置汇总

【TI-CCS笔记】工程编译配置 bin文件的编译和生成 各种架构的Post-build配置汇总 TI编译器分类 在CCS按照目录下 有个名为${CG_TOOL_ROOT}的目录 其下就是当前工程的编译器 存放目录为&#xff1a; C:\ti\ccs1240\ccs\tools\compiler按类型分为五种&#xff1a; ti-cgt-arm…

Appium Desktop安装

【提示&#xff1a;官方已不再维护&#xff0c;建议命令行方式安装&#xff0c;但可以学习了解一下】 Appium Desktop是一款适用于Mac、Windows和Linux的应用程序&#xff0c;它以漂亮灵活的UI为您提供Appium自动化服务器的强大功能。它基本上是Appium Server的图形界面。您可…

【嵌入式环境下linux内核及驱动学习笔记-(19)LCD驱动框架2-FrameBuffer】

目录 1、 Frmebuffer(帧缓冲&#xff09;操作介绍1.1 显示设备的抽象1.2 内存映像1.3 输出画面数据1.4 用户态下操作屏显1.4.1 用文件I / O 操作屏显1.4.2 mmap() 函数1.4.3 ioctl()函数1.4.5 用命令操作屏1.4.6 测试程序 2、Framebuffer总体框架2.1 框架要点2.2 fbmem.c分析2.…

算法通关村第三关【黄金】| 数组元素出现次数问题

1.数字出现的次数超过数组长度的一半 方法一、使用Map键值对来记录每个元素出现的次数&#xff0c;返回次数大于一半的 class Solution {public int majorityElement(int[] nums) {Map<Integer,Integer> map new HashMap<>();for(int i 0;i<nums.length;i){m…

深度学习入门-3-计算机视觉-图像分类

1.概述 图像分类是根据图像的语义信息对不同类别图像进行区分&#xff0c;是计算机视觉的核心&#xff0c;是物体检测、图像分割、物体跟踪、行为分析、人脸识别等其他高层次视觉任务的基础。图像分类在许多领域都有着广泛的应用&#xff0c;如&#xff1a;安防领域的人脸识别…

开源低代码平台Openblocks

网友 HankMeng 想看低代码工具&#xff0c;正好手上有一个&#xff1b; 什么是 Openblocks &#xff1f; Openblocks 是一个开发人员友好的开源低代码平台&#xff0c;可在几分钟内构建内部应用程序。 传统上&#xff0c;构建内部应用程序需要复杂的前端和后端交互&#xff0c;…

百度屏蔽词有哪些?其中就有移民关键词指数被屏蔽?

我是百收网SEO&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 今日tombkeeper消息爆料&#xff1a;百度指数已经屏蔽“移民”等关键词指数。 大家好&#xff0c;我是百收网SEO商学院的狂潮微课老师&#xff0c;今天我们来讲解第 12 节课关键词优化难度分析…

Markdown编辑器 Mac版Typora功能介绍

Typora mac是一款跨平台的Markdown编辑器&#xff0c;支持Windows、MacOS和Linux操作系统。它具有实时预览功能&#xff0c;能够自动将Markdown文本转换为漂亮的排版效果&#xff0c;让用户专注于写作内容而不必关心格式调整。 Typora Mac版除了支持常见的Markdown语法外&#…

国资委79号文解读:国央企OA办公系统信创替代落地实践与标杆案例

国资委79号文解读&#xff1a;国央企OA办公系统信创替代落地实践与标杆案例 2022年9月底&#xff0c;国资委下发了重要的国资发79号文件&#xff0c;全面指导并要求国央企落实信息化系统的信创国产化改造。其中&#xff0c;明确要求所有中央企业在2022年11月底前将安可替代总体…

Unity Spine帧事件

SpinePro中添加事件帧 首先 选中右上角的层级树 然后选择事件选项 最后在右下角看到 新建 点击它 新建一个事件 点击左上角的设置按钮 弹出编辑窗口 编辑窗口 在右上角 动画栏 可以切换对应的动画 点坐边的那个小灰点来切换 亮点代表当前动画 选中帧 添加事件 点击对应事件…

[机器学习]特征工程:特征降维

特征降维 1、简介 特征降维是指通过减少特征空间中的维度&#xff0c;将高维数据映射到一个低维子空间的过程。 在机器学习和数据分析中&#xff0c;特征降维可以帮助减少数据的复杂性、降低计算成本、提高模型性能和可解释性&#xff0c;以及解决维度灾难等问题。特征降维通…

Datawhale Django后端开发入门 TASK02 Admin管理员、外键的使用

1.Admin管理员的使用 先放一张成功的截图&#xff0c;记得自己创建时的账号和密码呀&#xff0c;如果忘了的话可以也是再重新创建管理员账号和密码的 &#xff0c;这个页面接下来就不用操作了,就要开始重要的 post 步骤。 二、外键的使用 我认为比较难的&#xff08;很不好操作…

【Spring 】了解Spring AOP

目录 一、什么是Spring AOP 二、AOP的使用场景 三、AOP组成 四、Spring AOP的实现 1、添加Spring AOP依赖 2、定义切面和切点 3、定义相关通知 五、 AOP的实现原理 1、什么是动态代理 2、 JDK代理和CGLIB代理的区别 一、什么是Spring AOP AOP&#xff08;Aspect Ori…

opencv-进阶05 手写数字识别原理及示例

前面我们仅仅取了两个特征维度进行说明。在实际应用中&#xff0c;可能存在着更多特征维度需要计算。 下面以手写数字识别为例进行简单的介绍。 假设我们要让程序识别图 20-2 中上方的数字&#xff08;当然&#xff0c;你一眼就知道是“8”&#xff0c;但是现在要让计算机识别…

SharkTeam:Worldcoin运营数据及业务安全分析

Worldcoin的白皮书中声明&#xff0c;Worldcoin旨在构建一个连接全球人类的新型数字经济系统&#xff0c;由OpenAI创始人Sam Altman于2020年发起。通过区块链技术在Web3世界中实现更加公平、开放和包容的经济体系&#xff0c;并将所有权赋予每个人。并且希望让全世界每一个人都…