java数据结构与算法刷题-----LeetCode106. 从中序与后序遍历序列构造二叉树

java二叉树的前序+中序+后序遍历(修改后) 二叉树的遍历,全部用递归实现,很有规律! 二叉树的遍历,全部用递归实现,很有规律 立即下载
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.youkuaiyun.com/grd_java/article/details/123063846

在这里插入图片描述

1. 法一:递归

解题思路:时间复杂度O(n),空间复杂度O(n),空间使用了一个Map,大小为中心遍历的长度,以及递归需要的栈空间
  1. 因为后序遍历[9,15,7,20,3]是左右中,它表示一个区间中,最后一个结点,是中间结点。比如[9,15,7,20,3]这个区间,正好是整个二叉树,共5个结点。那么这个区间的中间结点,也就是根节点为最后一个结点3.
  2. 而中序遍历[9,3,15,20,7]是左中右,它表示,只要找到中间结点,就可以分出左右两个区间来,比如[9,3,15,20,7]这个区间,已知3是根节点,那么[9]在其左子树,[15,20,7]在其右子树
  3. 所以思路很简单,我们先通过后序遍历序列,在区间中拿到最后一个结点,从而获取中间结点。然后通过中序遍历序列,获得其左右两个区间
  4. 然后其左右两个区间,因为后序遍历是左右中,中确定后,先确定右区间。

继续从后序遍历序列中,获取其最后一个结点20,20就是这个右子树的中间结点。

  1. 然后构造其左区间。依次类推,直到整颗二叉树完成构造。

后序遍历序列只需要从后往前依次遍历即可,因为只需要你做一遍后序遍历,就会发现,后序遍历的效果就是每一个中间结点,都按顺序排列在序列末尾

  1. 比如[9,15,7,20,3],根节点为3,3的右子树为20,20的右子树为7,此时通过中序遍历发现右边到头了
  2. 开始左子树构造,20的左子树为15, 然后15到头了。回到3 , 最后3的左子树为9. 9也到头了,没有结点了,构造完成

所以一定要注意,拿到中间结点后,先去右区间,右区间遍历完成后,再去左区间

代码

在这里插入图片描述

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int post_idx;//当前区间中结点的位置
    int[] postorder;//后序遍历
    int[] inorder;//中序
    //保存中序遍历中,每个结点在inorder数组中的下标
    Map<Integer, Integer> idx_map = new HashMap<Integer, Integer>();
    //后序:左右中
    //中序:左中右
    //每次确定一个“中”
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        this.postorder = postorder;
        this.inorder = inorder;
        // 从后序遍历的最后一个元素开始:因为后序:左右中,中结点始终在区间最后面
        post_idx = postorder.length - 1;

        // 建立(元素,下标)键值对的哈希表,保存中序inorder数组的结点下标位置
        int idx = 0;
        for (Integer val : inorder) {
            idx_map.put(val, idx++);
        }
        //helper通过中序和后序遍历构造二叉树,
        //每次在中序遍历的inorder数组规定区间,初始是全部从0到inorder.length-1
        //然后从后序遍历中获取中结点。
        return helper(0, inorder.length - 1);
    }

    public TreeNode helper(int in_left, int in_right) {
        // 如果这里没有节点构造二叉树了,就结束
        if (in_left > in_right) {
            return null;
        }

        // 选择 post_idx 位置的元素作为当前子树根节点
        int root_val = postorder[post_idx];//中结点,从后序遍历中获取
        TreeNode root = new TreeNode(root_val);

        // 根据 root 所在位置分成左右两棵子树
        int index = idx_map.get(root_val);//获取此结点在中序遍历中的位置
        //从而得到以此结点为中心的左右两个区间

        // 下标减一
        post_idx--;//下标前移,找到下一个中结点
        // 先构造右子树(先右区间)
        root.right = helper(index + 1, in_right);//进入当前中结点的右区间,再次构造
        // 构造左子树(然后再左区间)
        root.left = helper(in_left, index - 1);//进入当前中结点的左区间,再次构造
        return root;//返回当前root结点(中结点)。最终一定会返回根节点
    }

    
}

2. 法二:迭代

思路分析:时间复杂度O(n),空间复杂度O(n),空间只用了队列来模拟递归的栈,无需map
  1. 将中序和后序都反过来:中序变为右中左,后序变成右左中
  2. 初始我们可以直接通过后序获取根结点root
  3. 而如果我们倒着遍历中序序列的话,正好获得到root的右区间
  4. 当我们发现倒着遍历中序,找到了root,那么剩下的是左区间的
  5. 然后重复这个过程即可
代码

在这里插入图片描述

class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if (postorder == null || postorder.length == 0) {//没有结点直接返回null
            return null;
        }
        //后序序列最后一个,必然是根节点
        TreeNode root = new TreeNode(postorder[postorder.length - 1]);//根节点
        Deque<TreeNode> stack = new LinkedList<TreeNode>();//模拟栈
        stack.push(root);//根结点先入栈,是迭代法必须得
        int inorderIndex = inorder.length - 1;//中序遍历的下标
        for (int i = postorder.length - 2; i >= 0; i--) {//除去根节点外,依次从后往前遍历postorder后序序列
            int postorderVal = postorder[i];//获取后序序列,中结点
            TreeNode node = stack.peek();//获取栈顶元素
            //下面的inorder[inorderIndex],指向的是当前node中间结点的右区间最后一个元素
            if (node.val != inorder[inorderIndex]) {//如果栈顶不是中间结点,直到中序遍历找到中间
                node.right = new TreeNode(postorderVal);//那么先处理右区间
                stack.push(node.right);//入队列
            } else {//如果栈顶就是中间结点
                //如果没有遍历完成,并且栈顶就是当前中序遍历中间结点的话
                while (!stack.isEmpty() && stack.peek().val == inorder[inorderIndex]) {
                    node = stack.pop();//出栈这个中间结点node1,它们已经构造完成了右子树,该处理它的左子树了
                    inorderIndex--;//但是如果inorderIndex再次对上栈顶,说明node1这个结点没有左子树,还会继续while循环
                }
                //然后处理左区间
                node.left = new TreeNode(postorderVal);
                stack.push(node.left);
            }
        }
        return root;
    }
}

java二叉树的前序+中序+后序遍历 java实现 二叉树的遍历 前序遍历用到递归, 中序和后序遍历用到栈, 其实还是有一定难度的 立即下载

相关推荐

[逆向实战] 淘宝x5sec滑条验证码slidedata参数逆向与自动化过码方案

本文详细解析了淘宝x5sec滑条验证码的核心参数slidedata的生成机制与逆向过程,提供了Python自动化过码方案。通过分析滑动轨迹加密流程、还原AES加密算法,并设计人类行为模拟轨迹,帮助开发者有效绕过淘宝滑块验证,适用于爬虫开发与自动化测试场景。

weixin_30851867的博客 735

java 二叉树的实现以及前序、中序、后续遍历实现

二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点。本文主要讲的是二叉树中的完全二叉树的实现,

西凉的悲伤博客 839

一、5.8GHz射频接收机链路仿真

5.8GHz射频接收机链路仿真 一、5.8GHz射频接收机链路仿真 文章目录5.8GHz射频接收机链路仿真目的一、原理1、仿真工具2、二次下变频超外超接收机二、要求三、内容总结 目的   1、熟悉射频接收机整体结构。   2、学习使用MATLAB工具进行行为级仿真。   3、进行简单的通信链路预算。   4、直观感受接收机各个模块对整体性能的影响。   5、分析增益、线性度、噪声系数等参数。 一、原理 1、仿真工具   MATLAB是一款功能强大的数学软件,针对不同领域提供各种工具箱,帮助设计者快

平乾的博客 6761

Java实现二叉树的前序,中序,后序遍历(迭代,递归两种方法实现)

前言 二叉树,有深度优先遍历和广度优先遍历,但是这两个概念不止局限于二叉树,它们更是一种抽象的算法思想,决定了访问某些复杂数据结构的顺序。本文主要讲述深度优先遍历的三种方法! 所谓深度优先,顾名思义,就是偏向于纵深,“一头扎到底”的访问方式。这样说很抽象,下边我们就通过深度优先的前序,中序,后序三种遍历方式,来看一看深度优先把。 三种遍历思想: 前序遍历:根结点 ---> 左子树 ---> 右子树 中序遍历:左子树--->根结点---> 右子树 后序遍历:左子树 ...

qswdaw的博客 5230

Android流畅度优化实战:从掉帧定位到布局与渲染调优

在移动应用开发中,性能优化是决定用户体验与留存率的关键环节,其中Android流畅度优化更是核心命题。用户感知的“卡顿”往往并非持续低帧率,而是由于掉帧率波动引发的偶发不流畅。本文从性能优化理论出发,系统讲解如何使用Systrace、CPU Profiler等工具定位掉帧瓶颈,深入分析布局层级过深、过度绘制、对象分配与GC压力等常见诱因。同时结合冷启动耗时、列表滚动掉帧、Bitmap加载等真实工程案例,阐述从应用层到系统层的分级优化策略,并给出低端机适配、异步化改造及线上监控体系搭建的实践方案。内容覆盖布局

weixin_29185493的博客 201

嵌入式Linux网络调试:YT8531/YT8521 PHY驱动移植与设备树配置避坑指南

本文深入解析嵌入式Linux系统中YT8531/YT8521 PHY驱动移植与设备树配置的关键技术,涵盖内核驱动适配、RGMII接口时序调整及常见问题排查。针对Motorcomm千兆以太网PHY芯片,提供详细的设备树配置示例和调试技巧,帮助开发者规避典型设计陷阱,确保网络功能稳定运行。

weixin_42525632的博客 676

二叉树的遍历和基本操作(Java实现)

二叉树的三种遍历方式详细分解步骤,手把手教你保你学会。带你学会实现二叉树的所有基本操作代码,

qq_73471456的博客 3513

Ubuntu20.04下运行LOAM系列:A-LOAM、LeGO-LOAM、SC-LeGO-LOAM、LIO-SAM 和 LVI-SAM

在我第一篇博文Ubuntu 20.04配置ORB-SLAM2和ORB-SLAM3运行环境+ROS实时运行ORB-SLAM2+Gazebo仿真运行ORB-SLAM2+各种相关库的安装的基础环境下跑通A-LOAM首先已经按照上一篇文章已经安装好了ROS noetic、Eigen3.4.0、OpenCV4.2.0和PCL1.10,A-LOAM在Github的开源地址:https://github.com/HKUST-Aerial-Robotics/A-LOAM。接下来根据代码要求,需要安装Ceres,另外环境的变

zardforever123的博客 3万+

Java 实现 二叉树的 后序遍历

Java 实现 二叉树的 后序遍历

ideal-lingyun 776

深度解析:如何通过NodeRed实现私有485协议VRF中央空调与HomeAssistant的无缝对接

本文详细介绍了如何利用NodeRed的灵活流程化编程,破解并处理VRF中央空调的私有485协议,实现与HomeAssistant的无缝本地化集成。文章从协议分析、硬件准备到NodeRed核心流程搭建、数据映射及双向通信控制,提供了一套完整的实战方案,帮助用户将非标设备深度融入智能家居生态,摆脱对厂家云服务的依赖。

weixin_29173777的博客 408

Matlab:Matlab 软件学习之Matlab内置的各种系统的简介、案例应用(基于Simulink模糊控制仿真/二阶瞬态震荡电路案例)之详细攻略

选择左上角要编辑变量的图标,给定当前变量的论域Range,设置隶属函数类型type(八种隶属函数类型以供选择),最后选中某个隶属度函数(选中为红色),移动绘图区的每个隶属度函数的三个端点(竖向为权重)。(1)、首先在模糊规则编辑器左边选择一个输入变量,并选中它的一个语言值(隶属函数),然后编辑器右边选择一个输出变量,并选中它的一个语言值(隶属函数),然后将这种关系添加到模糊规则中。制定完成后,会形成模糊规则矩阵,系统会根据模糊输入量(如r1、r2),经过模糊规则(如45条),进而确定输出量(Y1、Y2)。

走向CTO之路 1123

Java~二叉树的前中后序遍历的几种方式(递归法,迭代法,标记法等)

一.结点的定义 首先这里先给出结点的定义,和leetcode树相关的题目都是这么定义结点的 class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() {} TreeNode(int val) { this.val = val; } TreeNode(int val, TreeNode left, TreeNode right) { th

Zebra的博客 1814

Allegro快速编辑丝印文字操作指导

选择setup-Application Mode-placement edit。Allegro支持丝印文字的编辑,下面介绍快速编辑丝印文字的两种方法如下。这个功能还支持拷贝粘贴,可以从其它地方拷贝过来,免去了书写的麻烦。出现text edit窗口,输入自己需要的文字,点击ok。鼠标移动到丝印文字位置,文字会被高亮起来。Allegro快速编辑丝印文字操作指导。点击丝印文字,丝印会被高亮起来。选择Text edit 命令。输入需要更改后的文字,如下。右击选择text edit。以编辑下方丝印文字为例。

weixin_54787054的博客 4193

Java实现 LeetCode 106 从中序与后序遍历序列构造二叉树

106. 从中序与后序遍历序列构造二叉树 根据一棵树的中序遍历与后序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树: 3 / \ 9 20 / \ 15 7 class Solution { ...

南 墙 1万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

LeetCode第106题:从中序与后序遍历序列构造二叉树的Java实现

LeetCode第106题要求使用一棵树的中序遍历和后序遍历序列来重建二叉树。本文将介绍两种Java实现方法:递归和迭代。LeetCode第106题是一个典型的树重建问题,通过理解二叉树的遍历特性,可以有效地利用中序和后序遍历序列重建二叉树。递归法直观易理解,而迭代法则更节省空间。

2301_77695569的博客 1040

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

LeetCode 106 / 105 从中序与后序 / 前序与中序遍历序列构造二叉树

文章目录LeetCode 106 从中序与后序遍历序列构造二叉树LeetCode 105 从前序与中序遍历序列构造二叉树 参考文章 LeetCode 106 从中序与后序遍历序列构造二叉树 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal 题意: 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树

今天你学习了吗? 1721

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

根据一棵树的中序遍历与后序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 中序遍历 inorder =[9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树: 3 / \ 9 20 / \ 15 7 思路:和前序中序构建二叉树思路一样。 /** * Definitio...

少说,多做。 2932

LeetCode刷题汇总

剑指offer 剑指 Offer 03 数组中重复的数字 剑指 Offer 04 二维数组中的查找 剑指 Offer 05 替换空格 剑指 Offer 06 从尾到头打印链表 剑指 Offer 07 重建二叉树 剑指 Offer 09 用两个栈实现队列 剑指 Offer 10- I 斐波那契数列 剑指 Offer 10- II 青蛙跳台阶问题 剑指 Offer 11 旋转数组的最小数字 剑指 Offer 12 矩阵中的路径 剑指 Offer 13 机器人的运动范围 剑指 Offer 14- I 剪绳子 剑指

weixin_44171872的博客 2万+

力扣106 从中序与后序遍历序列构造二叉树 java实现

摘要:本文介绍了如何根据二叉树的中序和后序遍历序列重建二叉树。后序遍历的最后一个元素是根节点,通过在中序遍历中找到该节点位置,可确定左右子树的范围。采用递归方法,分别处理左右子树的中序和后序序列,逐步构建完整二叉树。文中提供了Java实现代码示例,包括处理边界条件和分割数组的逻辑。该算法时间复杂度为O(n),适用于节点值不重复的二叉树重建场景。

m0_58648798的博客 1122

LeetCode 106. 从中序与后序遍历序列构造二叉树(Java)

链接 LeetCode:106. 从中序与后序遍历序列构造二叉树 题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 思路 同 《剑指offer》系列 重建二叉树(Java) 一样,后序遍历的最一个值为根节点的值,使用这个值将中序遍历结果分成两部分,左部分为树的左子树中序遍历的结果,右部分为树的右子树中序遍历的结

朱嫑膘的博客 292

leetcode 106.从中序与后序遍历序列构造二叉树 Java

从中序与后续遍历序列构造二叉树题目链接描述示例初始代码模板代码 题目链接 https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/ 描述 根据一棵树的中序遍历与后序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 示例 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树: 3

博主是个二次元死肥宅~ 346

瑞_力扣LeetCode_二叉树相关题

本文章为瑞_系列专栏之《刷题》的力扣LeetCode系列,主要以力扣LeetCode网的题进行解析与分享。本文主要是配合《瑞_数据结构与算法_二叉树》对二叉树的知识进行提升和拓展

阿瑞——从事Java后端,喜欢研读源码、自研框架、分享经验 1379

【LeetCode每日一题】[中等]106. 从中序与后序遍历序列构造二叉树

【LeetCode每日一题】[中等]617. 合并二叉树 617. 合并二叉树 题目来源 算法思想:树,递归 题目: java代码 class Solution { public TreeNode buildTree(int[] inorder, int[] postorder) { //递归生成二叉树 return dfsbuild(inorder, postorder, postorder.length-1, 0, inorder.length); } privat

qq_39457586的博客 168

LeetCode Java面试刷题笔记汇总

LeetCode Java刷题笔记汇总,按照类型刷题效率更高。

终生学习践行者 2948
上一篇: java数据结构与算法刷题-----LeetCode404. 左叶子之和
下一篇: java数据结构与算法刷题-----LeetCode513. 找树左下角的值
ydenergy_殷志鹏
博客等级 码龄7年 5886粉丝 543原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值