297. 二叉树的序列化与反序列化

news2024/9/25 17:21:39

297. 二叉树的序列化与反序列化

难度困难

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

示例 1:

输入:root = [1,2,3,null,null,4,5]
输出:[1,2,3,null,null,4,5]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

输入:root = [1,2]
输出:[1,2]

提示:

  • 树中结点数在范围 [0, 104] 内
  • -1000 <= Node.val <= 1000

前序/后序遍历

  • 将二叉树转化为字符串-->序列化
    • 使用前序遍历(后序遍历也可以,中序遍历不行因为不能找到根节点索引)
    • 如果节点为空节点利用#拼接,每个节点利用逗号分隔开(在节点后拼接逗号)
    • 如果节点不为空,利用对应val值进行拼接,每个节点利用逗号分隔开(在节点后拼接逗号)
  • 将字符串转化为二叉树-->反序列化
    • 首先将对应字符串使用split按照,分隔开,就转化为一个字符串数组(数组中就对应字符串形式的二叉树节点值)
    • 将对应字符串形式的二叉树节点值 加入到 linkedlist 中,然后进行反序列化
    • 接下来就要根据字符串来构造一颗二叉树了,同样也要根序列化统一,使用前序遍历按照顺序构造即可(list一次从头部弹出,弹到空为止)
      • 如果list为空则返回null
      • 如果弹出字符串为#,返回给父节点为null
      • 如果弹出字符串不为#,那就构造对应节点值,返回给父节点
      • 接着构造左树,构造右树
    • 返回构造好的根节点
public class Codec {
    
    private StringBuilder res = new StringBuilder();
    private void serializeDFS(TreeNode root) {
        if(root==null) {
            res.append("#").append(",");
            return;
        }
        res.append(root.val).append(",");
        serializeDFS(root.left);
        serializeDFS(root.right);
    }

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        serializeDFS(root);
        return res.toString();
    }

    private TreeNode deserializeDFS(LinkedList<String> list) {
        if(list.isEmpty()) {
            return null;
        }
        String str = list.removeFirst();
        if(str.equals("#")) {
            return null;
        }
        TreeNode root = new TreeNode(Integer.parseInt(str));
        root.left = deserializeDFS(list);
        root.right = deserializeDFS(list);
        return root;
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        LinkedList<String> list = new LinkedList<>();
        for(String s : data.split(",")) {
            list.add(s);
        }
        return deserializeDFS(list);
    }
}

// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));

层序遍历

  • 将二叉树转化为字符串-->序列化
    • 使用层序遍历,这次也要将空拼接到字符串中(拼接#),不为空拼接对应值,借点后面拼接逗号
  • 将字符串转化为二叉树-->反序列化
    • 首先将对应字符串使用split按照,分隔开,就转化为一个字符串数组(数组中就对应字符串形式的二叉树节点值)
    • 使用一个队列进行层序遍历(放入节点值)构造一颗二叉树
      • 每次从队列中弹出节点作为根节点
      • 遍历下一个字符,如果为#,构造左树为null ,如果不为#,构造左树,为左树对应节点值,然后将左树加入到队列中
      • 遍历下一个字符,如果为#,构造右树为null ,如果不为#,构造右树,为右树对应节点值,然后将右树加入到队列中
    • 直到队列为空,就生成号一颗二叉树
public class Codec {
    private StringBuilder res = new StringBuilder();
    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if(root==null) return "";
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int sz = queue.size();
            for(int i =0;i<sz;++i) {
                TreeNode cur = queue.poll();
                if(cur==null){
                    res.append("#").append(",");
                    continue;
                }
                res.append(cur.val).append(",");
                queue.offer(cur.left);
                queue.offer(cur.right);
            }
        }
        return res.toString();
    }
    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if(data.length()==0) return null;
        String[] str = data.split(",");
        TreeNode root = new TreeNode(Integer.parseInt(str[0]));
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        for(int i =1;i<str.length;) {
            TreeNode parent = queue.poll();
            if(!str[i].equals("#")) {
               parent.left = new TreeNode(Integer.parseInt(str[i]));
               queue.offer(parent.left);
            }else {
                parent.left = null;
            }
            i++;
            if(!str[i].equals("#")) {
                parent.right = new TreeNode(Integer.parseInt(str[i]));
                queue.offer(parent.right);
            }else {
                parent.right = null;
            }
            i++;
        }
        return root;
    }
}

// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));

总结 :

使用#进行拼接,使用逗号进行分割开,然后对应着反序列化就按照逗号分隔开转化成字符传数组再加入到list中好进行处理(比如list为empty就知道遍历结束,不用复杂处理字符串).

中序遍历由于找不到根节点索引,无法序列化反序列化

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

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

相关文章

Linux:查看服务器信息,CPU、内存、系统版本、内核版本等

还是最近工作的总结&#xff0c;性能验证要根据服务器的配置才能做进一步的结论论证&#xff0c;废话不多说 目录查看Linux内核版本查看Linux系统版本CPU查看CPU信息&#xff08;型号&#xff09;物理CPU个数每个物理CPU中core的个数(即核数)查看逻辑CPU的个数内存查看内存信息…

【C语言航路】第十三站:动态内存管理

目录 一、为什么存在动态内存分配 二、动态内存函数 1.内存的分区 2.malloc和free &#xff08;1&#xff09;malloc和free库函数文档 &#xff08;2&#xff09;malloc和free的使用 2.calloc &#xff08;1&#xff09;calloc的库函数文档 &#xff08;2&#xff09;c…

模糊图像检测(c++)

Opencv-模糊检测 - 知乎图像清晰度&#xff0c;是指影像上各细部影纹及其边界的清晰程度。 解决问题&#xff1a;由于前端摄像机视频中聚焦不当&#xff0c;异物遮挡等原因&#xff0c;所引起的画面视野图像模糊的现象。 算法原理&#xff1a;将彩色图像转化为灰度图像&#xf…

Python深度学习基础(九)——深入浅析卷积核

深入浅析卷积核引言单通道卷积简单图像边缘检测锐化高斯滤波引言 提到卷积&#xff0c;应该多数人都会想到类似上图的这种示例&#xff0c;可以简单的理解成卷积核与图像中和卷积核相同大小的一块区域与卷积核相乘再求和&#xff0c;通过移动区域产生一个有和组成的新的图像&am…

黑马学ElasticSearch(十二)

目录&#xff1a; &#xff08;1&#xff09;ES集群-集群结构介绍 &#xff08;2&#xff09;es集群-搭建集群 &#xff08;3&#xff09;es集群-集群职责及脑裂 &#xff08;4&#xff09;es集群-分布式新增和查询流程 &#xff08;5&#xff09; es集群-故障转移 &#…

传输层协议:TCP协议(下)——运作方式(如何三次握手、四次挥手等)

运作方式 TCP协议的运行可划分为三个阶段&#xff1a;连接创建(connection establishment)、数据传送&#xff08;data transfer&#xff09;和连接终止&#xff08;connection termination&#xff09;。操作系统将TCP连接抽象为套接字表示的本地端点&#xff08;local end-p…

【PyTorch】教程:学习基础知识-(6) Autograd

AUTOMATIC DIFFERENTIATION WITH torch.autograd 在训练神经网络时&#xff0c;最常用的算法是反向传播算法&#xff0c;在该算法中&#xff0c;参数根据损失函数相对于给定参数的梯度进行调整。 为了计算这些梯度&#xff0c; PyTorch 有一个内置的微分引擎 torch.autograd …

2022秋招算法岗面经题:训练模型时loss除以10和学习率除以10真的等价吗(SGD等价,Adam不等价)

问题描述&#xff1a;训练深度学习模型时loss除以10和学习率除以10等价吗&#xff1f; 先说结论 这个问题的答案与优化器有关 使用Adam、Adagrad、RMSprop等带有二阶动量vtv_tvt​的优化器训练时&#xff0c;当我们将loss除以10&#xff0c;对训练几乎没有影响。使用SGD、Mo…

Streamlit自定义组件开发教程

在这篇文章中&#xff0c;我们将学习如何构建Streamlit组件以及如何发布streamlit组件供其他人使用。 使用 3D场景编辑器快速搭建三维数字孪生场景 1、什么是Streamlit组件&#xff1f; Streamlit 组件是一个可共享的 Streamlit 插件&#xff0c;可让你为应用程序添加新的视觉…

Java——子集

题目链接 leetcode在线oj题——子集 题目描述 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 题目示例 输入&#xff1a;nums [1,2,3] …

MySQL管理

1&#xff1a;MySQL管理1.1&#xff1a;系统数据库Mysql数据库安装完成后&#xff0c;自带了一下四个数据库&#xff0c;具体作用如下&#xff1a; 数据库 含义 mysql 存储MySQL服务器正常运行所需要的各种信息 &#xff08;时区、主从、用 户、权限等&#xff09; information…

性能测试/实战演示 H5 性能分析

W3C标准是浏览器标准&#xff0c;一般浏览器都支持W3C标准&#xff0c;它规定使用者可以通过api查询性能信息&#xff0c;可借用W3C协议完成自动化H5性能测试。 W3C官网&#xff1a;Navigation Timing 使用chrome浏览器对webview进行手工查看&#xff0c;伴随着业务增多&#x…

mysql:索引的数据结构,B树,B+树浅聊

mysql&#xff1a;索引的数据结构 什么是索引&#xff1f; 索引&#xff08;Index&#xff09;是帮助MySQL高效获取数据的数据结构 为什么学索引&#xff1f; 之前应该有概念说&#xff0c;把索引理解为目录&#xff0c;比如通过s就可以查询到s开头的汉子从哪也开始&#xff…

[网鼎杯 2020 青龙组]AreUSerialz

目录 信息收集 代码审计 前提知识 思路分析 绕过检测 方法一 poc payload 方法二 poc payload 信息收集 进入页面给出了源代码如下&#xff0c;是一道PHP的反序列化题目 <?phpinclude("flag.php");highlight_file(__FILE__);class FileHandler {pro…

Linux多线程 线程概念 | 线程VS进程 | 线程控制【万字精讲】

线程 一、线程概念 1. 知识支持及回顾 在我们一开始学习进程的时候。我们总说进程在内部执行时&#xff0c;是OS操作系统调度的基本单位。其实并不严谨&#xff0c;今天&#xff0c;我们要重新完善这个说法——线程在进程内部运行&#xff0c;线程是OS操作系统调度的基本单位…

WorkPlus移动办公平台,助力企业随时随地“指尖办公”

近年来&#xff0c;随着移动互联网的发展&#xff0c;越来越多的人习惯于随时随地通过移动设备完成工作、购物、游戏等。移动办公应用就是基于移动终端的信息化办公应用&#xff0c;利用企微、钉钉、WorkPlus等移动办公平台&#xff0c;实现企业与员工间的随时随地工作、沟通&a…

技术分享 | ClickHouse StarRocks 使用经验分享

作者&#xff1a;许天云 本文来源&#xff1a;原创投稿 *爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。 一. 大纲 本篇分享下个人在实时数仓方向的一些使用经验&#xff0c;主要包含了ClickHouse 和 StarRocks 这两款目…

ASP.NET MVC解决方案的搭建(.NET Framework)——C#系列(一)

一、新建项目 1、控制器新建 2、Service层新建 3、Business数据层新建 4、Commons公共层新建 5、Models实体层新建 二、调用接口 1、接口建立 Web API 2 控制器新建 2、调用 三、Swagger接口调试配置 1、添加NuGet包 在启动项中添加Swashbuckle NuGet包 2、访问 htt…

Vivado2018.3安装及注册指南-安装包获取

一、vivado 介绍 vivado设计套件 是FPGA 厂商赛灵思&#xff08;Xilinx&#xff09;公司最新的为其产品定制的集成开发环境&#xff0c;支持Block Design、Verilog、VHDL等多种设计输入方式&#xff0c;内嵌综合器以及仿真器&#xff0c;可以完成从设计输入、综合适配、仿真到…

mysql存储过程的基础知识

本文来简单说下存储过程的基础知识 文章目录概述什么是存储过程存储过程的优缺点概述 mysql官网提供的储存过程&#xff1a;https://www.mysqlzh.com/doc/225/499.html 什么是存储过程 简单的说&#xff0c;存储过程是一条或者多条SQL语句的集合&#xff0c;可视为批文件&…