【力扣每日一题】2023.9.4 序列化和反序列化二叉搜索树

目录

题目:

示例:

分析:

代码:


题目:

示例:

分析:

题目给我们一棵搜索二叉树,要我们将这棵二叉树转变为字符串,同时我们需要根据字符串再变回二叉树,具体的方法我们可以自行制定。

这道题让我想起了力扣的另外一道题:

我们可以把二叉树的前序遍历和中序遍历的结果压缩成字符串。

要由字符串变为二叉树的时候,可以通过字符串分割出前序遍历和中序遍历,再通过前序与中序遍历序列构造二叉树。

因此我们今天的重点放在这道105题上。

我们应该如何通过前序遍历的结果和中序遍历的结果来构造二叉树?

我们先看看两者的结果分别有什么特点。

我们知道,前序遍历和中序遍历对于二叉树的遍历顺序是一样的,都是先遍历左子树再遍历右子树,不一样的是,取节点值的时机不同,前序遍历是在一开始就去了当前节点的值,而中序遍历是在递归遍历完了当前节点的左子树之后才取的值。

因此前序遍历的结果的值的顺序就是我们递归二叉树的顺序,因为前序遍历一递归到节点就取值,因此前序遍历的第一个元素一定是根节点。

而中序遍历,用我的话来说,就是把二叉树压扁,说起来比较抽象。可以参考下面的动图看一看。

因为二叉树压扁之后就是中序遍历的结果,所以结果里某个节点的左边的节点,都在这个节点的左子树上,在这节点右边的节点,都在这个节点的右子树上。

大概懂了两种遍历结果的特点之后,我们来分析如何通过这俩结果来构造一棵二叉树。

我们就以105题的示例一为例。        

中序遍历的结果是:

[ 9 , 3 , 15 , 20 , 7]

前序遍历的结果是:

[ 3 , 9 , 20 , 15 , 7 ]

根据我们刚才说的,前序遍历的结果的第一个元素就是根节点。因此我们构造出的二叉树的根节点的值就是前序遍历的第一个值:3。

而3在中序遍历中,将结果分为了两半,【9】和【15,20,7】。

又根据我们刚才说的,【9】在原本3的左边,所以9在3的左子树,【15,20,7】在3的右边,所以它们仨在3的右子树上。

3的左子树就9一个节点,所以我们可以知道根节点的左子树节点的值就是9,那么问题在于右子树节点的值,有三个备选的值都在右子树上,那么哪一个值是根节点的右子树的根节点的值呢?

这时候我们就需要看前序遍历了,按照顺序来看,开头的3和9我们都用过了,那么接下来轮到的是20,所以根节点的右子树节点的值就是20。

20在中序遍历中,将剩余的结果又分为了两半,是15和7,分别是20的左右子树。至此遍历完毕,我们也就构造完了二叉树。

我们知道如何用前序遍历和中序遍历的结果构造二叉树之后我们再回过头来看看今天的每日一题。

前序遍历和中序遍历相信大家都懂,我们先分别将两个结果集的每个元素之间用一个特殊符号来连接起来,代码中我用的是‘#’,再用另一个特殊符号来连接两个结果集,代码中我用的是‘/’。如此我们就将一棵二叉树序列化了。

反序列化的话,我们只需将前序遍历的结果和中序遍历的结果从序列化后的字符串中提取出来,然后直接使用105题的代码就可以,我在代码中也是这么做的。

我这种做法没有利用到搜索二叉树的特性,并且代码又臭又长,所以仅供大家参考,提供一种思路,可以参考下面的动图来体会一下怎么通过前序和中序遍历来构造二叉树。

代码:

class Codec {
public:vector<int>cache;void qianxv(TreeNode* root){    //前序遍历if(root==nullptr) return;cache.push_back(root->val);qianxv(root->left);qianxv(root->right);}void zhongxv(TreeNode* root){   //中序遍历if(root==nullptr) return;zhongxv(root->left);cache.push_back(root->val);zhongxv(root->right);}// Encodes a tree to a single string.string serialize(TreeNode* root) {  //将前序和中序的结果拼接cache.clear();qianxv(root);string res="";for(auto c:cache) res+="#"+to_string(c);res+='/';   //中间用'/'分隔cache.clear();zhongxv(root);for(auto c:cache) res+="#"+to_string(c);return res;}//力扣105题,前序与中序构造二叉树TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {if(inorder.size()==0) return nullptr;TreeNode* res=new TreeNode(preorder[0]);    //根节点一定是前序遍历的第一个int index=0;for(;index<inorder.size();index++){if(inorder[index]==preorder[0]) break;  //找到根节点在中序遍历的位置}   preorder.erase(preorder.begin());   //移除前序遍历第一个节点vector<int>left,right;//中序遍历的位置的左边是当前节点的左子树if(index!=0) left=vector<int>(inorder.begin(),inorder.begin()+index);//中序遍历的位置的右边是当前节点的右子树  if(index!=inorder.size()-1) right=vector<int>(inorder.begin()+index+1,inorder.end());//传入更新过的前序遍历和中序遍历来构造左右子树res->left=buildTree(preorder,left);res->right=buildTree(preorder,right);return res;}// Decodes your encoded data to tree.TreeNode* deserialize(string data) {vector<int>preorder,inorder;int index=0;while(data[index]!='/'){if(data[index]=='#'){string temp="";index++;while(data[index]!='#'&&data[index]!='/'){temp+=data[index];index++;}preorder.push_back(stoi(temp));}}index++;while(index<data.size()){if(data[index]=='#'){string temp="";index++;while(index<data.size()&&data[index]!='#'){temp+=data[index];index++;}inorder.push_back(stoi(temp));}}return buildTree(preorder,inorder);}
};

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

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

相关文章

Linux之虚拟主机功能

目录 虚拟主机功能 概述 基于 IP 地址的虚拟主机 原理 案例 --- 增加多个IP地址&#xff0c;实现基于不同IP地址的虚拟主机功能 基于端口号的虚拟主机 原理 案例 --- 基于不同端口号的虚拟主机 基于域名的虚拟主机 原理 域名解析 案例 --- 使用2个域名建立虚拟主机网…

Mysql 高阶语句

高阶语句 对 MySQL 数据库的查询&#xff0c;除了基本的查询外&#xff0c;有时候需要对查询的结果集进行处理&#xff1b; 例如只取 10 条数据、对查询结果进行排序或分组等&#xff0c;来获取想要有用的数据 无非还是对于MySQL —— 增、删、改、查 的操作 升降序 SELECT…

基于单片机的万年历温度无线传输控制系统系统

一、系统方案 本设计采用DS1302采集年月日时分秒&#xff0c;DS18B20采集温度值&#xff0c;按键设置温度报警上下限&#xff0c;实际测量温度低于下限或高于上限&#xff0c;蜂鸣器报警&#xff0c;同时将测量温度上传到蓝牙助手。 二、硬件设计 原理图如下&#xff1a; 三…

R语言图形的组合( par(),layout(),par(fig()) )

引入d.class进行画图 > d.class<-read.csv("D://class.csv",header T) > attach(d.class) > opar<-par(no.readonly TRUE)非常简单的数据&#xff0c;需要可自取 链接&#xff1a;https://pan.baidu.com/s/1zNx5z9JsaaRqFueRgGY3mQ 提取码&#x…

3D开发工具HOOPS Publish如何快速创建交互式3D PDF文档?

HOOPS Publish是一款功能强大的SDK&#xff0c;可以创作丰富的工程数据并将模型文件导出为各种行业标准格式&#xff0c;包括PDF、STEP、JT和3MF。HOOPS Publish核心的3D数据模型是经过ISO认证的PRC格式(ISO 14739-1:2014)&#xff0c;它为装配树、拓扑和几何、产品制造信息和视…

Seata1.5.2+Nacos分布式事务环境搭建详解

文章目录 一、下载seata server二、配置application.yml三、初始Mysql数据库四、导入初始配置到nacos五、启动测试 本文以seata-server-1.5.2&#xff0c;以配置中心、注册中心使用Nacos&#xff0c;store.modedb&#xff08;mysql&#xff09;为例进行操作。 Seata简介及入门参…

[深度学习]1. 深度学习知识点汇总

本文记录了我在学习深度学习的过程中遇到过的不懂的知识点&#xff0c;为了方便翻阅&#xff0c;故将其发表于此&#xff0c;随时更新&#xff0c;供大家参考。 深度学习常见知识点 1. 测试精度和训练精度 在深度学习中&#xff0c;测试精度和训练精度是两个重要的指标&#…

【zip密码】zip压缩包删除密码方法

Zip压缩包设置设置了密码&#xff0c;想要删除密码&#xff0c;除了将压缩包解压出来之后再将文件压缩为不带密码的压缩文件以外&#xff0c;还有一种删除密码的方法。设置方法如下&#xff1a; 右键点击zip文件&#xff0c;找到打开方式&#xff0c;以Windows资源管理器方式打…

VBA技术资料MF52:VBA_在Excel中突出显示前 10 个值

【分享成果&#xff0c;随喜正能量】一言之善&#xff0c;重于千金。善良不分大小&#xff0c;有时候你以为的一句话&#xff0c;小小的举手之劳&#xff0c;也可能就是别人的救赎&#xff01;不要吝啬你的善良&#xff0c;因为你永远不知道那小小的善良能给多少人带来光明。。…

【 ARMv9 Cluster BUS QoS 配置】

文章目录 ARM Cluster QoS ARM Cluster QoS QoS&#xff08;Quality of Service&#xff0c;服务质量&#xff09;在 ARM 架构中&#xff0c;主要指的是一种机制&#xff0c;它可以控制和管理系统资源&#xff08;如内存、总线带宽等&#xff09;的使用&#xff0c;以满足各种…

Cyber RT学习---5.Cyber RT通信机制解析与实践

5.Cyber RT通信机制解析与实践 5.1 通信机制简介 5.1.1 话题通信 模式&#xff1a; 以发布订阅的方式实现不同节点之间数据交互的通信模式。 如图1-1所示&#xff0c;Listener-Talker通信首先创建了两个Node&#xff0c;分别是Talker Node和 Listener Node。 每个Node实例化…

【B树 B+树】B树、B+树理论

目录 引入B树B树定义和性质m阶B树核心特性 B树B树的查找 引入B树 满足上面两个策略就是B树&#xff1a; m 叉查找树中&#xff0c;规定除了根节点外&#xff0c;任何结点至少有 ⌈ m / 2 ⌉ \lceil m/2 \rceil ⌈m/2⌉ 个分叉&#xff0c;即至少含有 ⌈ m / 2 ⌉ \lceil m/2 \…

Python爬虫——新手使用代理ip详细教程

Python代理IP爬虫是一种可以让爬虫拥有更多网络访问权限的技术。代理IP的作用是可以为爬虫提供多个IP地址&#xff0c;从而加快其爬取数据的速度&#xff0c;同时也可以避免因为访问频率过高而被网站封禁的问题。本文将介绍如何使用Python实现代理IP的爬取和使用。 一、代理IP的…

RHCA之路---EX280(10)

RHCA之路—EX280(10) 1. 题目 On master.lab.example.com install the OpenShift Mertics component with the following requirements: Use the storage /exports/metrics for cassandra storage. You can use the files on http://materials.example.com/exam280/storage fo…

海康威视二次开发适配安卓电视盒子

收到一个需求&#xff0c;需要在安卓电视盒子上适配海康威视摄像头视频&#xff1a; 1.类似电视家app界面&#xff0c;左边滑动菜单显示通道列表、设置按钮&#xff0c;遥控器呼出菜单。 2.遥控器操作&#xff1a;切换视频通道、云台上下左右控制、缩放等。 3.服务器域名、用…

FPGA输出lvds信号点亮液晶屏

1 概述 该方案用于生成RGB信号&#xff0c;通过lvds接口驱动逻辑输出&#xff0c;点亮并驱动BP101WX-206液晶屏幕。 参考&#xff1a;下面为参考文章&#xff0c;内容非常详细。Xilinx LVDS Output——原语调用_vivado原语_ShareWow丶的博客http://t.csdn.cn/Zy37p 2 功能描述 …

RabbitMQ的安装和配置

将RabbitMQ文件夹传到linux根目录 开启管理界面及配置

【VSCode】文件模板创建及使用.md

背景 最近使用VSCode学习Vue项目比较频繁&#xff0c;每次创建Vue文件都要手动写重复代码&#xff0c;特别麻烦&#xff0c;就上网查找自动生成代码的说明&#xff0c;结果发现VSCode有代码模板&#xff0c;怪怪&#xff0c;感觉发现新大陆了(low!)。 配置 打开配置 方式一&a…

手机电脑scoket通信 手机软件 APP inventor 服务端程序python

python scoket 通信 再帮助同学坐课题的时候接触到了scoket通信&#xff0c;了解到这应该是基层网络通信的原理&#xff0c;于是就导出搜索了一下相关的资料&#xff0c;简单来说scoket通信就是&#xff0c;可以让不同设备在同一个网络环境的条件下&#xff0c;可以实现相互通…

ubuntu20.04+ROS noetic在线运行单USB双目ORB_SLAM

双目摄像头主要有以下几种&#xff0c;各有优缺点。 1.单USB插口&#xff0c;左右图像单独输出2.双USB插口&#xff0c;左右图像单独输出&#xff08;可能存在同步性问题&#xff09;3.双USB插口&#xff0c;左右图像合成输出4.单USB插口&#xff0c;左右图像合成输出 官方版…