【算法数据结构初阶篇】:105. 从前序与中序遍历序列构造二叉树

news/2024/11/24 0:09:29/

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

核心点:
1.前序遍历:根左右 ;中序遍历:左根右

2.从前序遍历中的子树preorder,第一个元素即为根节点,创建出根节点head,最后用来返回

3.接着就从中序遍历中的子树inorder,遍历找到根节点对应的索引find,[L2,find)即为左子树元素,(find,R2]即为右子树元素,find - L2的根节点到左子树边界距离长度就等同于中序遍历中根节点到左子树边界距离,从而来确定左子树的右边界: L1 + find - L2 ,其余边界同理推断

4.然后开始用根节点head递归去构造head.left head.right左右子树

5.L1 > R1边界溢出,这点很重要容易忽略,会出现二叉树是一个单边树,即左子树空或者右子树空,此时就会存在越界情况:比如先序 中序 都为[1,2,3] (左子树为空) ,根节点1,中序遍历中索引find=0,再往左找左子树递归就溢出了。head.left = f(preorder, L1 + 1, L1 + find - L2, inorder, L2, find - 1,valueIndexMap); 此时L1 + find - L2 = L1 因为第一轮find跟L2重叠 所以就变成L1+1,L1 溢出,则需要返回空
/*** 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 {public TreeNode buildTree(int[] preorder, int[] inorder) {//提前记录中序遍历的头节点对应索引的Map,用来查询出中序遍历中哪个是根节点,对应的索引,就不用每次递归子树时都要循环查找中序遍历的根节点HashMap<Integer,Integer> valueIndexMap = new HashMap<>();for(int i = 0; i < inorder.length; i++){valueIndexMap.put(inorder[i], i);}return f(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1, valueIndexMap);}// 有一棵树,先序结果是pre[L1...R1],中序结果是in[L2...R2]// 请建出整棵树返回头节点public TreeNode f(int[] preorder, int L1, int R1, int[] inorder, int L2, int R2, HashMap<Integer,Integer> valueIndexMap){//存在某些情况下 会越界溢出//比如 先序 中序 都为[1,2,3] (左子树为空) 那么确定好根节点1,中序遍历中该根节点在索引find=0,在往左找左子树递归就溢出了。head.left =  f(preorder, L1 + 1, L1 + find - L2, inorder, L2, find - 1,valueIndexMap); 此时L1 + find - L2 = L1  因为第一轮find跟L2重叠 所以就变成L1+1,L1 溢出,返回空if(L1 > R1) return null;//先序遍历 根左右,索引第一个即为根节点 取出TreeNode head = new TreeNode(preorder[L1]);//当子树中只有自己的时候则直接返回根节点if(L1 == R1)return head;//从中序遍历中,找到根节点L1对应的索引find ,那么 从[0,find-1]皆为左子树的节点,//[find+1,R2]皆为右子树的节点,然后就开始分别左递归,右递归去构建树int find = valueIndexMap.get(preorder[L1]);//递归左子树:确定先序遍历的左子树左右边界:左边界就是从L1+1,因为L1是根节点,根据中序遍历根节点索引find往左的元素都为左子树元素,find - L2 表示根节点到左子树左边界的距离,那么在先序遍历中根节点加上这个距离就得到左子树的右边界了。 因为两边同个子树长度一定相等。 所以右边界为 L1+find-L2;    而中序遍历的左子树左右边界:就是find节点左侧那一堆数 L2,find-1//head.left = f(preorder, L1 + 1, L1 + find - L2, inorder, L2, find - 1,valueIndexMap);//递归右子树同理head.right = f(preorder,L1 + find - L2 + 1, R1, inorder, find + 1, R2,valueIndexMap);//最后需要返回根节点return head;}
}

http://www.ppmy.cn/news/22909.html

相关文章

oracle在线增加redo日志组成员

文档课题&#xff1a;oracle在线增加redo日志组成员. 数据库&#xff1a;oracle11.2.0.4 操作过程 SYSorcl>select group#,bytes/1024/1024 "size(M)",status,archived from v$log; GROUP# size(M) STATUS ARC -------------------- ---------------- --- 1…

MySQL库的操作

文章目录库的操作创建数据库创建数据库案例字符集和校验规则校验规则对数据库的影响不区分大小写区分大小写进行查询结果排序查看数据库修改数据库数据库删除查看连接情况库的操作 创建数据库 语法&#xff1a; CREATE DATABASE [IF NOT EXISTS] db_name [create_specificat…

【C/C++基础练习题】复习题卷二

1.对一个类中的数据成员的初始化可以通过构造函数中的( )实现&#xff0c;也可以通过构造函数中的( )实现。&#xff08;初始化表&#xff0c;函数体&#xff09; 2.假定AB为一个类&#xff0c;则执行“AB a[10];”语句时&#xff0c;系统自动调用该类的构造函数的次数为( 10)…

python小游戏——打砖块代码开源

♥️作者&#xff1a;小刘在这里 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的&#xff0c;绽放&#xff0c;愿所有的美好&#…

java.lang.NoClassDefFoundError: org.joda.time.ReadablePeriod错误的处理

若依引入了activiti,开发环境是好的,发布到linux环境报错: Exception in thread "main" java.lang.NoClassDefFoundError: org/joda/time/ReadablePeriod at org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl.initBusinessCalendarManager(ProcessEng…

【刷题篇】顺序表

1.前言 在之前&#xff0c;我们学习了顺序表的概念与实现&#xff0c;其基本概念如下&#xff1a; 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;是线性表中的一种&#xff0c;分为静态顺序表和动态顺序表。一般情况下采用数组存储&#xff0c;…

力扣19.删除链表的倒数第N个结点(C++)

目录 1.题目描述 2.代码 1.题目描述 19.删除链表的倒数第N个结点 【中等】 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#…

从CNN到Transformer:基于PyTorch的遥感影像、无人机影像的地物分类、目标检测、语义分割和点云分类

目录 专题一&#xff1a;深度卷积网络知识详解 专题二&#xff1a;PyTorch应用与实践&#xff08;遥感图像场景分类&#xff09; 专题三&#xff1a;卷积神经网络实践与目标检测 专题四&#xff1a;卷积神经网络的遥感影像目标检测任务案例【FasterRCNN】 专题五&#xff…