Leetcode 剑指 Offer II 048. 二叉树的序列化与反序列化

news/2024/7/24 13:24:37 标签: leetcode, linux, 算法

题目难度: 困难

原题链接

今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~

题目描述

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

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

示例 1:

leetcode.com%2Fuploads%2F2020%2F09%2F15%2Fserdeser.jpg&pos_id=img-KrYnM55G-1697248706368" alt="外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传" />

  • 输入: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]

提示:

  • 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,也可以采用其他的方法解决这个问题。
  • 树中结点数在范围 [0, 10^4] 内
  • -1000 <= Node.val <= 1000

题目思考

  1. 如何定位节点之间的关系?

解决方案

思路
  • 既然题目没有限制序列化和反序列化的算法, 我们就怎样简单怎样来
  • 如果我们给每个节点一个唯一的下标, 同时保存它的父节点下标, 以及父节点对当前节点的指向(即左还是右子节点), 当然还有节点本身的值, 这样就能唯一确定整棵树了
  • 根据这个思路, 我们序列化的时候就可以使用 BFS, 用一个四元组保存上述信息, 最后转成字符串即可
  • 反序列化就更简单了: 使用字典保存下标到值的映射关系(下标唯一), 因为保存的时候是 BFS 逐层遍历的, 所以当要转换某个节点时, 其父节点一定已经转换好并保存在字典中了, 这样就能拿到父节点, 再根据指向决定当前是左还是右子节点即可
  • 下面的代码对必要的步骤都有详细的解释, 方便大家理解
复杂度
  • 时间复杂度 O(N): 每个节点只需要遍历一次
  • 空间复杂度 O(N): 队列的空间消耗, 因为是四元组, 所以是 O(4*N) = O(N)
代码
class Codec:
    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        if not root:
            return ''
        # 注意这里用List而不是Tuple存四元组, 用于下标赋值
        q = [[0, -1, 'L', root]]
        i = 1
        for t in q:
            # 此处只需要关心当前节点下标, 以及当前节点自身即可, 不用管当前节点的父节点和父节点指向
            p, _, _, node = t
            if node.left:
                q.append([i, p, 'L', node.left])
                i += 1
            if node.right:
                q.append([i, p, 'R', node.right])
                i += 1

        def convertToStr(t):
            # 将节点转成对应的值
            t[3] = t[3].val
            # 然后将当前四元组转成字符串
            return ','.join(str(x) for x in t)

        q = [convertToStr(t) for t in q]
        # 最后将数组转成字符串, 注意此处的分隔符要和上面的四元组分隔符区分开来
        return '+'.join(q)

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        if not data:
            return None
        # 拆分成字符串数组
        data = data.split('+')
        maps = {}
        root = None
        for t in data:
            # 进一步拆分出四元组
            i, p, direction, val = t.split(',')
            node = TreeNode(int(val))
            if i == '0':
                # 保存根节点
                root = node
            # 将当前节点存入字典中
            maps[i] = node
            if p in maps:
                # 父节点存在, 更新指向关系
                parent = maps[p]
                if direction == 'L':
                    parent.left = node
                else:
                    parent.right = node
        return root

大家可以在下面这些地方找到我~😊

我的 GitHub

我的 Leetcode

我的 CSDN

我的知乎专栏

我的头条号

我的牛客网博客

我的公众号: 算法精选, 欢迎大家扫码关注~😊

<a class=算法精选 - 微信扫一扫关注我" />


http://www.niftyadmin.cn/n/5088991.html

相关文章

QUIC协议

1、QUIC 简介 QUIC 全称&#xff1a;Quick UDP Internet Connections&#xff0c;是一种基于 UDP 的传输层协议。由 Google 自研&#xff0c;2012 年部署上线&#xff0c;2013 年提交 IETF&#xff0c;2021 年 5 月&#xff0c;IETF 推出标准版 RFC9000。 从协议栈可以看出&am…

在命令行下使用Apache Ant

Apache Ant的帮助文档 离线帮助文档 在<ant的安装目录>/manual下是离线帮助文档 双击index.html可以看到帮助文档的内容&#xff1a; 在线帮助文档 最新发布版本的帮助文档https://ant.apache.org/manual/index.html Apache Ant的命令 ant命令行格式 ant [opt…

三维地下管线建模软件MagicPipe3D V3.1.3发布

经纬管网建模系统MagicPipe3D V3.1.3持续更新&#xff0c;内容如下&#xff1a; &#xff08;1&#xff09;新增管线流向配置&#xff0c;建模生成带流向箭头管道模型&#xff1b; &#xff08;2&#xff09;新增建模完成后可以直接载入3DTiles或obj模型功能&#xff1b; &a…

运算符【Java基础】

[TOC]&#xff08;运算符&#xff09; 运算符概述 一种特殊的符号&#xff0c;有以下功能 数据的运算数据的比较数据的赋值 算术运算符 &#xff08;正号、加号、字符串拼接&#xff09;-&#xff08;负号、减号&#xff09;*&#xff08;乘&#xff09;/&#xff08;取模&a…

案例|美创科技守护健康“一盘棋”,医共体整体数据安全建设实践

以医共体之“通”&#xff0c;破解看病之“痛”。在县域组建医疗共同体&#xff0c;逐步实现区域内医疗资源共享&#xff0c;推动形成基层首诊、双向转诊、急慢分治、上下联动的分级诊疗模式&#xff0c;是实现“首诊在基层、大病不出县”&#xff0c;更好地为全县人民群众服务…

【23】c++设计模式——>代理模式

代理模式定义 C中的代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许通过引入一个代理对象来控制对另一个对象的访问。 代理模式通常涉及以下几个角色&#xff1a; 1.抽象主题&#xff08;Subject&#xff09;&#xff1a;定义了真实主题…

1.用Python做一个Web网页需要学习什么

需要学习以下几个方面&#xff1a; 1.基本的Python编程知识&#xff1a;了解Python语法和常用的编程概念&#xff0c;包括变量、数据类型、控制流、循环、函数等。 2.网络编程基础知识&#xff1a;了解HTTP协议、URL结构、请求和响应等基本概念。 3.Web框架&#xff1a;选择一种…

Spring MVC 和Spring JDBC

目录 Spring MVC MVC模式 核心组件 工作流程 Spring JDBC Spring JDBC功能和优势 Spring JDBC的关键组件 Spring MVC Spring MVC&#xff08;Model-View-Controller&#xff09;是Spring框架的一个模块&#xff0c;用于构建Web应用程序。它的主要目标是将Web应用程序的不…