通过遍历结果构造二叉树

news2025/1/18 8:38:18

请添加图片描述
⭐️前言⭐️

本篇文章主要总结通过前序遍历、中序遍历、后序遍历中的两个遍历结果,来构造二叉树的过程,通过本篇文章的总结,可以解决一下问题。

LeetCode难度
654. 最大二叉树🟠
105. 从前序与中序遍历序列构造二叉树🟠
106. 从中序与后序遍历序列构造二叉树🟠
889. 根据前序和后序遍历构造二叉树🟠
剑指 Offer 07. 重建二叉树🟠

🍉欢迎点赞 👍 收藏留言评论 📝私信必回哟😁

🍉博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言

🍉博客中涉及源码及博主日常练习代码均已上传GitHub


请添加图片描述

📍内容导读📍

  • 🍅构建最大二叉树
  • 🍅前序中序构建
  • 🍅中序后序构建
  • 🍅前序后序构建

🍅构建最大二叉树

654. 最大二叉树
在这里插入图片描述
在这里插入图片描述
题解思路:
首先遍历数组找到最大值maxValue,从而把根节点root构造出来,然后对maxValue左边的数组和右边的数组进行递归构建,作为root的左右子树。

按照题目给出的例子,输入的数组为[3,2,1,6,0,5],对于整棵树的根节点来说,其实是在做这件事。

TreeNode constructMaximumBinaryTree([3,2,1,6,0,5]) {
    // 找到数组中的最大值
    TreeNode root = new TreeNode(6);
    // 递归调用构造左右子树
    root.left = constructMaximumBinaryTree([3,2,1]);
    root.right = constructMaximumBinaryTree([0,5]);
    return root;
}

代码实现:

/* 主函数 */
TreeNode constructMaximumBinaryTree(int[] nums) {
    return build(nums, 0, nums.length - 1);
}

// 定义:将 nums[lo..hi] 构造成符合条件的树,返回根节点
TreeNode build(int[] nums, int lo, int hi) {
    // base case
    if (lo > hi) {
        return null;
    }

    // 找到数组中的最大值和对应的索引
    int index = -1, maxVal = Integer.MIN_VALUE;
    for (int i = lo; i <= hi; i++) {
        if (maxVal < nums[i]) {
            index = i;
            maxVal = nums[i];
        }
    }

    // 先构造出根节点
    TreeNode root = new TreeNode(maxVal);
    // 递归调用构造左右子树
    root.left = build(nums, lo, index - 1);
    root.right = build(nums, index + 1, hi);
    
    return root;
}

🍅前序中序构建

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

剑指 Offer 07. 重建二叉树

在这里插入图片描述
题解思路:
前序遍历的第一个值preorder[0]就是根节点的值,通过在中序遍历中找到该值,就确定了左右子树值的范围。将划分开的区域递归下去进行构建,就完成了二叉树的构建。
在这里插入图片描述

leftSize:左子树节点的个数=index-inStart

代码实现:

class Solution {
    HashMap<Integer,Integer> valToIndex=new HashMap<>();
    // 通过哈希表存储中序遍历数据对应的索引
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        for(int i=0;i<inorder.length;i++) {
            valToIndex.put(inorder[i],i);
        }
        return build(preorder,0,preorder.length-1,
                    inorder,0,inorder.length-1);
    }

    TreeNode build(int[] preorder,int preStart,int preEnd,
                    int[] inorder,int inStart,int inEnd) {
        if(preStart>preEnd) {
            return null;
        }
        int rootVal=preorder[preStart];
        int index=valToIndex.get(rootVal);
        int leftSize=index-inStart;
		// 先构造出当前根节点
        TreeNode root=new TreeNode(rootVal);
        // 递归构造左右子树
        root.left=build(preorder,preStart+1,preStart+leftSize,
                        inorder,inStart,index-1);
        root.right=build(preorder,preStart+leftSize+1,preEnd,
                        inorder,index+1,inEnd);
        return root;
    }
}

🍅中序后序构建

106. 从中序与后序遍历序列构造二叉树
在这里插入图片描述
题解思路:
与上题前序、中序遍历结果构建相似,只是二叉树的根节点是后序遍历的最后一个节点,确定根节点后再去中序遍历中找到位置,划分左右子树,后续操作与上题相似。
在这里插入图片描述
代码实现:

class Solution {
    HashMap<Integer,Integer> map=new HashMap<>();
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for(int i=0;i<inorder.length;i++) {
            map.put(inorder[i],i);
        }
        return buildTree(inorder,0,inorder.length-1,
                        postorder,0,postorder.length-1);
    }

    TreeNode buildTree(int[] inorder,int inStart,int inEnd,
                        int[] postorder,int postStart,int postEnd) {
        if(inStart>inEnd) {
            return null;
        }
        int rootValue=postorder[postEnd];
        int index=map.get(rootValue);
        int leftSize=index-inStart;
        TreeNode root=new TreeNode(rootValue);
        root.left=buildTree(inorder,inStart,index-1,
                            postorder,postStart,postStart+leftSize-1);
        root.right=buildTree(inorder,index+1,inEnd,
                            postorder,postStart+leftSize,postEnd-1);
        return root;
    }
}

🍅前序后序构建

889. 根据前序和后序遍历构造二叉树
在这里插入图片描述
题解思路:
通过前序中序,或者后序中序遍历结果可以确定唯一一棵二叉树,但是通过前序后序遍历结果无法确定唯一的一棵二叉树,所以该题返回一种可能即可。

构造思路与上边的题目类似。
1.首先把前序遍历结果的第一个元素或者后序遍历的最后一个元素确定为根节点的值。
2.然后把前序遍历结果的第二个元素作为左子树的根节点的值。
(其实左子树有可能为空指针,所以答案不唯一)
3.在后序遍历结果中寻找左子树根节点的值,从而确定了左子树的索引边界,进而确定右子树的索引边界,递归构造左右子树即可。
在这里插入图片描述
代码实现:

class Solution {
   HashMap<Integer, Integer> valToIndex = new HashMap<>();

    public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
        for (int i = 0; i < postorder.length; i++) {
            valToIndex.put(postorder[i], i);
        }
        return build(preorder, 0, preorder.length - 1,
                    postorder, 0, postorder.length - 1);
    }

    TreeNode build(int[] preorder,int preStart,int preEnd,
                    int[] postorder,int postStart,int postEnd) {
        if (preStart > preEnd) {
            return null;
        }
        if (preStart == preEnd) {
            return new TreeNode(preorder[preStart]);
        }

        // root 节点对应的值就是前序遍历数组的第一个元素
        int rootVal = preorder[preStart];
        // root.left 的值是前序遍历第二个元素
        // 通过前序和后序遍历构造二叉树的关键在于通过左子树的根节点
        // 确定 preorder 和 postorder 中左右子树的元素区间
        int leftRootVal = preorder[preStart + 1];
        // leftRootVal 在后序遍历数组中的索引
        int index = valToIndex.get(leftRootVal);
        // 左子树的元素个数
        int leftSize = index - postStart + 1;

        // 先构造出当前根节点
        TreeNode root = new TreeNode(rootVal);
        root.left=build(preorder,preStart+1,preStart+leftSize,
                        postorder,postStart,index);
        root.right=build(preorder,preStart+leftSize+1,preEnd,
                        postorder,index+1,preEnd-1);
        return root;
    }
}

⭐️最后的话⭐️
总结不易,希望uu们不要吝啬你们的👍哟(^U^)ノ~YO!!如有问题,欢迎评论区批评指正😁

请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编程辅助插件BitoAI使用指南(以VSCode开发环境为例安装并使用BitoAI插件从而提高生产效率)

2023年是AI爆发元年&#xff0c;已经被各种AI工具、新闻轰炸了几个月&#xff0c;只有一种感觉&#xff1a;时间不够用&#xff01; 本文介绍编程辅助神器&#xff1a;Bito AI。 本插件使用与ChatGPT相同的模型&#xff01;目前免费&#xff0c;且拥有强大的辅助能力&#xff0…

高压放大器应用之无损检测

在高压放大器的应用中&#xff0c;很多电子工程师经常会进行无损检测实验&#xff0c;那么无损检测是什么&#xff0c;无损检测的知识又有哪些呢&#xff0c;就让安泰电子带大家来看看。 无损检测是什么&#xff1a; 无损检测是指不损害物品的情况下对产品进行检测的方法&#…

FFMPEG源码分析一 av_register_all()

我们在使用FFMPEG库时&#xff0c;第一个调用的就是av_register_all()&#xff0c;这个函数到底做了什么&#xff0c;有什么用&#xff0c;这里做个简单分析。 本文基于雷霄骅博客学习而来。详情请移步FFmpeg源代码结构图 - 编码_ffmpeg源码结构_雷霄骅的博客-CSDN博客 解析和…

Vsync信号和SurfaceFlinger刷新机制;打造智能车厢的关键技术

概述 车载智能座舱系统在现代汽车中已经越来越常见&#xff0c;它可以提供各种功能&#xff0c;例如音乐、导航和驾驶辅助等。要实现这些功能&#xff0c;需要底层硬件和系统软件的支持。其中&#xff0c;Vsync信号和SurfaceFlinger刷新机制是车载智能座舱系统中的两个关键技术…

无人驾驶——ros_canopen安装

上篇文章提到过&#xff0c;对于CAN测试&#xff0c;不能完全依靠CAN卡对应的软件&#xff0c;指导老师推荐了ros_canopen、socketcan_interface方法。记录一下使用该方法的过程。 安装ros_canopen,对应ros版本git clone下载资源并安装。 https://github.com/ros-industrial…

camunda如何启动一个流程

在 Camunda 中启动一个流程需要使用 Camunda 提供的 API 或者用户界面进行操作。以下是两种常用的启动流程的方式&#xff1a; 1、通过 Camunda 任务列表启动流程&#xff1a;在 Camunda 任务列表中&#xff0c;可以看到已经部署的流程&#xff0c;并可以点击“Start”按钮&am…

【Linux】Mysql事务

一、什么是事务 Mysql 数据库中不是所有的存储引擎都实现了事务处理。 支持事务的存储引擎有&#xff1a; InnoDBNDB Cluster 。不支持事务的存储引擎代表有&#xff1a; MyISAM 事务简单来说&#xff1a;一个 Session 中所进行所有的操作&#xff0c;要么同时成功&#xff0c…

CMU15445 - Project 0. C++ Primer(在写)

文章目录 系列笔记作业链接TASK 1GetPutRemove Task 2 系列笔记 环境配置 Project 0. C Primer (ing) 作业链接 作业链接&#xff08;2020&#xff0c;废&#xff09; 作业链接 p0就是一个C水平测试&#xff0c;很简单 2023的明显难不少。 TASK 1 先简单说一下看到这个数据…

linux 目录常用操作

1.linux复制粘贴命令 CtrlShiftC 复制 CtrlShiftV 粘贴 2.中断执行 CtrlC 键“保留”用于停止命令 3.终端清屏 clear 4.显示当前路径 pwd 5.进入目录 cd 目录名称 返回上级目录 cd .. 6.查看当前目录 ls查看详细信息 ls -l 7.创建目录&#xff08;可以理解为文件夹&…

怎么将太大的word文档压缩变小,3个高效方法

怎么将太大的word文档压缩变小&#xff1f;word文档是我们在办公中使用较多的文件格式之一&#xff0c;相信小伙伴们会遇到这样的问题&#xff0c;编辑完成word文档之后发现&#xff0c;编辑完的文档体积太大了&#xff0c;无论是发送给客户还是上传到邮箱中都不方便&#xff0…

pdf转成word | ppt | jpg图片,免费一键转换教程

我不允许真的还有人不知道如何免费将pdf转成 ppt、word 或者 jpg图片&#xff01; 职场小伙伴是不是会经常遇到pdf怎么转成word&#xff0c;pdf怎么转成word&#xff0c;pdf怎么jpg图片等问题&#xff1f;别再为pdf转化格式难、而且还要付费而发愁了&#xff01;这份pdf免费一…

设计模式-行为型模式之观察者模式

3. 观察者模式 3.1. 模式动机 建立一种对象与对象之间的依赖关系&#xff0c;一个对象发生改变时将自动通知其他对象&#xff0c;其他对象将相应做出反应。在此&#xff0c;发生改变的对象称为观察目标&#xff0c;而被通知的对象称为观察者&#xff0c;一个观察目标可以对应多…

重学Java设计模式-行为型模式-迭代器模式

重学Java设计模式-行为型模式-迭代器模式 内容摘自&#xff1a;https://bugstack.cn/md/develop/design-pattern/2020-06-23-重学 Java 设计模式《实战迭代器模式》.html#重学-java-设计模式-实战迭代器模式「模拟公司组织架构树结构关系-深度迭代遍历人员信息输出场景」 迭代…

R -- 用psych包做主成分分析

主成分分析 主成分分析是一种数据降维方式&#xff0c;他将大量相关变量转化为一组很少的不相关的变量&#xff0c;这些不相关的变量称为主成分。 人话版&#xff1a;给你发一个由18位数字组成的身份证号码&#xff0c;第1、2位数字表示所在省份的代码&#xff1b;第3、4位数…

深度学习笔记之残差网络(ResNet)

深度学习笔记之残差网络[ResNet] 引言引子&#xff1a;深度神经网络的性能问题核心问题&#xff1a;深层神经网络训练难残差网络的执行过程残差网络结构为什么能够解决核心问题残差网络的其他优秀性质 引言 本节将介绍残差网络( Residual Network,ResNet \text{Residual Netwo…

C#中用程序代码修改了datagridview中的数据,保存时只对光标当前行有保存解决办法

C#中DataGridView绑定了DataTable后&#xff0c;通过代码修改DataGridView中的数据&#xff0c;总有一行&#xff08;被修改过并被用户选中的行集合中索引为0的行&#xff09;不能被UpDate回数据库的问题和解决办法 长江黄鹤 2017-06-26 | 300阅读 | 1转藏 转藏全屏朗读分…

【JavaScript】初入前端,记录JavaScript学习过程

文章目录 一、下面将是你在本教程中学到的主要内容1. JavaScript直接写入HTML输出流2. JavaScript对事件的反应3. JavaScript&#xff1a;改变 HTML 内容4. JavaScript 改变HTML图像5. 改变HTML样式6. JavaScript 验证输入 二、JavaScript 语法学习1. JavaScript的位置2. 浏览器…

如何在硬盘上恢复已经删除的照片?

可以从硬盘恢复删除的照片吗&#xff1f; 旅行后&#xff0c;许多人倾向于将照片保存到另一个储存设备作为副本或备份。例如&#xff0c;将它们存储在外部硬盘上或将图片传输到电脑。但是在整理照片的时候&#xff0c;很可能不小心把照片删掉了&#xff0c;尤其是使用外接硬…

成都爱尔樊映川:视网膜上视觉最敏锐部位,出问题怎么办

视网膜后极部有一直径约 2mm 的浅漏斗状小凹陷区&#xff0c;该区含有丰富的叶黄素呈现椭圆形黄色&#xff0c;称为“黄斑”&#xff0c;是视网膜上视觉最敏锐的部位。 它主要与精细视觉及色觉等视功能有关。正常情况下&#xff0c;外界物体光线进入眼内&#xff0c;投影在黄斑…

【项目开发】二开系统,费了好大劲,才整好,规划业务逻辑太重要了

作为程序员一天不写代码&#xff0c;不会咋样&#xff0c;第二天会比较生疏&#xff0c;所以小编也不能闲着&#xff0c; 3天的时间吧&#xff0c;搞了个羽毛球场地预约系统&#xff0c;看着场地预约页面比较简单&#xff0c; 小编下班回家&#xff0c;搞了2个晚上&#xff0c…