1028. 从先序遍历还原二叉树(三种方法:栈+递归+集合)

2024-02-29 22:28

本文主要是介绍1028. 从先序遍历还原二叉树(三种方法:栈+递归+集合),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1028. 从先序遍历还原二叉树(三种方法:栈+递归+集合)
    • 一、栈+ while迭代
      • 1.思路
      • 2.代码
    • 二、递归法
      • 1.思路
      • 2.代码
    • 三、集合存储
      • 1.思路
      • 2.代码


1028. 从先序遍历还原二叉树(三种方法:栈+递归+集合)


在这里插入图片描述
在这里插入图片描述

一、栈+ while迭代

1.思路

1.遍历整个字符串,从0开始,根节点在第0层
2.用level记录层数,每遇到一个-字符,当前层数+1
3.用val记录要插入的结点的值,遍历取到的数字,通过字符运算得到值。
4.找到当前要插入结点的父结点,栈的大小要小于当前层数
5.如果节点只有一个子节点,那么保证该子节点为左子节点。
6.将创建的新结点入栈
7.除了根节点,其他子节点全部出栈,返回根节点

2.代码

    public TreeNode recoverFromPreorder(String traversal) {Stack<TreeNode> stack = new Stack<>();//用栈来存储结点for (int i = 0; i < traversal.length(); ) {//遍历整个字符串,从0开始,根节点在第0层int level = 0;//记录当前层数while (traversal.charAt(i) == '-') {//每遍历到一个-,层数累加level++;i++;}int val = 0;//查看当前要插入结点的数字while (i < traversal.length() && traversal.charAt(i) != '-') {//当前的字符是数字,并且未超过字符串val = val * 10 + (traversal.charAt(i) - '0');//根据字符的相加,遍历字符串找数字时 只能一个数字一个数字的转,// 但是字符串中连续的数字是一个多位数,需要前面的数字*10变高位,再加上后面的数,// 成为一个数,作为新结点的值i++;}while (stack.size() > level) {stack.pop();//找到当前要插入结点的父结点}TreeNode node = new TreeNode(val);//创建新结点if (!stack.isEmpty()) {//如果节点只有一个子节点,那么保证该子节点为左子节点。if (stack.peek().left == null) {stack.peek().left = node;} else {stack.peek().right = node;}}stack.add(node);//入栈}while (stack.size() > 1) {stack.pop();//要返回根节点,出到栈只有一个结点}return stack.pop();}

二、递归法

1.思路

1.利用helper函数,根据字符和对应深度创建结点,还原二叉树
2.每遇到-字符,层数加一
3.如果遍历的深度和获取到的深度不一致,返回空
4.当深度等于层数时,下一个结点的位置从index + level开始
5.通过字符运算获取数字,同时创建结点
6.根节点的左树调用helper函数递归,如果左子节点是空,那么右子节点肯定也是空的
7.如果根节点的左树不为空,要想添加结点,递归右树。
8.最终返回根节点

2.代码

    //102. 二叉树的层序遍历---递归写法int index = 0;//index记录遍历到字符串的哪个位置public TreeNode recoverFromPreorder3(String traversal) {return helper(traversal,0);}public TreeNode helper(String s, int depth) {//helper函数用来创建二叉树int level = 0;//记录层数while (index + level < s.length() && s.charAt(index + level) == '-') {level++;}//如果遍历的深度和获取到的深度不一致,返回空if (level != depth){return null;}int next = index + level;//获取数字while (next < s.length() && s.charAt(next) != '-')next++;int val = Integer.parseInt(s.substring(index + level, next));index = next;//创建结点TreeNode root = new TreeNode(val);root.left = helper(s, depth + 1);if (root.left == null) {//如果左子节点是空,那么右子节点肯定也是空的root.right = null;} else {root.right = helper(s, depth + 1);}return root;}

三、集合存储

1.思路

1.使用正则匹配把字符串S拆成不同的数字存进数组中,用集合list来存储结点
2.将根节点添加到list中,层数从1开始,不包括根节点
3.数组存储的位置不为空时,根据转换的值创建结点
4.将结点加入到集合中
5.获取父结点,插入结点,并从新设置层数,果满了,层数加一
6.最终返回根节点

2.代码

    //102. 二叉树的层序遍历--正则匹配public TreeNode recoverFromPreorder2(String traversal) {String[] valus = traversal.split("-");//使用正则匹配把字符串S拆成不同的数字,用集合list来存储结点List<TreeNode> list = new ArrayList<>();list.add(new TreeNode(Integer.valueOf(valus[0])));//根节点//根节点添加到list中int level = 1;//层数层1开始,不包括根节点for (int i = 1; i < valus.length; i++) {if (!valus[i].isEmpty()) {//数组存储的位置不为空TreeNode node = new TreeNode(Integer.valueOf(valus[i]));//根据转化的值,创建结点//因为是前序遍历,每层我们只需要存储一个结点即可,这个节点值有可能//会被覆盖,如果被覆盖了说明这个节点以及他的子节点都以及遍历过了,//所以不用考虑被覆盖问题list.add(level, node);//将结点加入到集合中TreeNode parent = list.get(level - 1);//获取父结点,插入结点,并从新设置层数if (parent.left == null) {parent.left = node;} else {parent.right = node;}level = 1;} else {level++;//如果满了,层数加一}}return list.get(0);}

点击移步博客主页,欢迎光临~

偷cyk的图

这篇关于1028. 从先序遍历还原二叉树(三种方法:栈+递归+集合)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760303

相关文章

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

504 Gateway Timeout网关超时的根源及完美解决方法

《504GatewayTimeout网关超时的根源及完美解决方法》在日常开发和运维过程中,504GatewayTimeout错误是常见的网络问题之一,尤其是在使用反向代理(如Nginx)或... 目录引言为什么会出现 504 错误?1. 探索 504 Gateway Timeout 错误的根源 1.1 后端

MySQL 表空却 ibd 文件过大的问题及解决方法

《MySQL表空却ibd文件过大的问题及解决方法》本文给大家介绍MySQL表空却ibd文件过大的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录一、问题背景:表空却 “吃满” 磁盘的怪事二、问题复现:一步步编程还原异常场景1. 准备测试源表与数据

python 线程池顺序执行的方法实现

《python线程池顺序执行的方法实现》在Python中,线程池默认是并发执行任务的,但若需要实现任务的顺序执行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录方案一:强制单线程(伪顺序执行)方案二:按提交顺序获取结果方案三:任务间依赖控制方案四:队列顺序消

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

使用Java读取本地文件并转换为MultipartFile对象的方法

《使用Java读取本地文件并转换为MultipartFile对象的方法》在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求,在这种场景下,MultipartFile对象非... 目录1. 基本需求2. 自定义 MultipartFile 类3. 实现代码4. 代码解析5. 自定