20200616

题目(难度:困难):

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

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

示例

你可以将以下二叉树:1/ \2   3/ \4   5序列化为 "[1,2,3,null,null,4,5]"

说明

不要使用类的成员 / 全局 / 静态变量来存储状态,你的序列化和反序列化算法应该是无状态的。

官方答案

官方提供的解法暂无 javascript,根据官方逻辑使用 javascript 实现:

深度优先搜索

二叉树的序列化本质上是对其值进行编码,更重要的是对其结构进行编码。
可以遍历树来完成上述任务。众所周知,我们一般有两个策略:BFS / DFS。

TreeNode:val 当前指针指的值,left 上一个值,right 下一个值

  • val -> 1 left -> 2 right -> 3
  • val -> 2 left -> null right -> null
  • val -> 3 left -> 4 right -> 5
  • val -> 4 left -> null right -> null
  • val -> 5 left -> null ight -> null
  1. TreeNode 序列化(TreeNode -> String)
  • 任选一个字符可以得到其 left 和 right 则
  • 递归找到所有字符拼接成字符串
  1. 字符串 反序列化(String -> TreeNode)
  • 先讲字符串转换成数组
  • 遍历数组分别对没有下赋值 left 及 right
/*** Definition for a binary tree node.* function TreeNode(val) {*     this.val = val;*     this.left = this.right = null;* }*//*** Encodes a tree to a single string.** @param {TreeNode} root* @return {string}*/
var serialize = function (root) {if (root === null || root.val === null) return 'null,'return root.val + ',' + serialize(root.left) + serialize(root.right)
}/*** Decodes your encoded data to tree.** @param {string} data* @return {TreeNode}*/
var deserialize = function (data) {function tree(list) {if (list.length === 0);let val = list.shift()if (val === 'null') return nulllet node = new TreeNode(val)node.left = tree(list)node.right = tree(list)return node}let list = data.split(',')return tree(list)
}
/*** Your functions will be called as such:* deserialize(serialize(root));*/

其他解法

BFS

序列化 —— 常规的 BFS

  • null 节点也入列,说它是真实节点也行,它有对应的"X",只是没有子节点入列
  • 考察出列节点
    • 如果不为 null,则将它的值推入 res 数组,并将它的左右子节点入列
    • 如果是 null 节点,则将 ‘X’ 推入 res 数组
  • 出列、入列,直到队列为空,所有节点遍历完,res 数组也构建完,转成字符

反序列化——也是 BFS,父节点出列,子节点入列

  • 除了第一个 ROOT 值,其他节点值都成对出现,分别对应左右子节点
  • 我们从第二项开始遍历,每次考察两个节点值
  • 因为先生成的节点,会成为之后生成的节点的父亲,用一个 queue 暂存一下
  • queue 初始放入根节点。父节点出列即考察它,新创建的子节点入列

同时考察父节点,和两个子节点值

  • 出列的父节点,它对应到指针指向的左子节点值,和指针右边的右子节点值

    • 如果子节点值不为 ‘X’ ,则为它创建节点,成为父节点的子节点,并作为未来的父节点入列
    • 如果子节点值为 ‘X’,什么都不做
  • 所有父节点(真实节点)都会在 queue 里走一次
/*** Encodes a tree to a single string.** @param {TreeNode} root* @return {string}*/
var serialize = function (root) {const queue = [root]let res = []while (queue.length) {const node = queue.shift()if (node) {// 出列的节点 带出子节点入列res.push(node.val)queue.push(node.left) // 不管是不是null节点都入列queue.push(node.right)} else {res.push('X')}}return res.join(',')
}
/*** Decodes your encoded data to tree.** @param {string} data* @return {TreeNode}*/
var deserialize = function (data) {if (data == 'X') return null // 就一个'X',只有一个nullconst list = data.split(',') // 序列化字符串转成list数组const root = new TreeNode(list[0]) //首项是根节点值,为它创建节点const queue = [root] // 初始放入root,待会出列考察let cursor = 1 // 从list第二项开始遍历while (cursor < list.length) {// 指针越界const node = queue.shift() // 父节点出列考察const leftVal = list[cursor] // 获取左子节点值const rightVal = list[cursor + 1] // 获取右子节点值if (leftVal !== 'X') {// 左子节点值是有效值const leftNode = new TreeNode(leftVal) // 创建节点node.left = leftNode // 成为当前出列节点的左子节点queue.push(leftNode) // 它是未来的爸爸,入列等待考察}if (rightVal !== 'X') {// 右子节点值是有效值const rightNode = new TreeNode(rightVal) // 创建节点node.right = rightNode // 成为当前出列节点的右子节点queue.push(rightNode) // 它是未来的爸爸,入列等待考察}cursor += 2 // 指针前进2位}return root // 返回根节点
}

菜鸟的自白

这道题本地调试有点曲折
题目提示了:

// Definition for a binary tree node.
function TreeNode(val) {this.val = valthis.left = this.right = null
}// Your functions will be called as such:
deserialize(serialize(root))

但是在本地调试的时候还是有点地方要修改的:

  • 引入 TreeNode 函数
  • 反序列化需要传入序列化之后的数据,那本地先声明一个 reeNode 形式的序列化数据就太麻烦了
  • serialize(deserialize(‘1,2,3,null,null,4,5’))
  • 反向调用先传入 String -> Object -> String 来验证逻辑

博客: 小书童博客(http://gaowenju.com)

公号: 坑人的小书童

一天一大 leet(二叉树的序列化与反序列化)难度:困难 DAY-16相关推荐

  1. [Java]LeetCode297. 二叉树的序列化与反序列化 | Serialize and Deserialize Binary Tree

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  2. python代码实现二叉树的序列化和反序列化

    python代码实现二叉树的序列化和反序列化 二叉树的序列化 二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字 符串,从而使得内存中建立起来的二叉树可以持久保存. 二叉树的反序 ...

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

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

  4. 算法练习day10——190328(二叉树的先序、 中序、 后序遍历, 包括递归方式和非递归方式、找到一个节点的后继节点、二叉树的序列化和反序列化)

    1.实现二叉树的先序. 中序. 后序遍历, 包括递归方式和非递归方式 1.1 访问节点的顺序 节点访问顺序如下图所示: 访问顺序:1 2 4 4 4 2 5 5 5 2 1 3 6 6 6 3 7 7 ...

  5. 【数据结构与算法】之深入解析“二叉树的序列化与反序列化”的求解思路与算法示例

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

  6. 数据结构与算法之二叉树的序列化和反序列化及判断一棵树是否为平衡二叉树

    数据结构与算法之二叉树的序列化和反序列化及判断一棵树是否为平衡而二叉树 目录 二叉树的序列化和反序列化 判断一棵树是否为平衡而二叉树 1. 二叉树的序列化和反序列化 1. 递归版本序列化和反序列化 代 ...

  7. 【LeetCode】【HOT】297. 二叉树的序列化与反序列化(BFS)

    [LeetCode][HOT]297. 二叉树的序列化与反序列化 文章目录 [LeetCode][HOT]297. 二叉树的序列化与反序列化 package hot;import java.util. ...

  8. lintcode 7. 二叉树的序列化和反序列化 Python代码

    '''7. 二叉树的序列化和反序列化 描述 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为"序列化",读取文件后重建同样的二叉树被称为"反序列化 ...

  9. leetcode-017-297. 二叉树的序列化与反序列化

    我又又又开始刷题了... 不过这么一天两个小时,其实还是蛮浪费时间的,毕竟我对C++其实并不是特别熟悉,所以很多时候花费在语法上面的时间,就很磨人. 序列化是将一个数据结构或者对象转换为连续的比特位的 ...

最新文章

  1. STM32 基础系列教程 20 - RTC
  2. 技巧 | Java 8 Stream 中异常处理的4种方式
  3. Bootstrap(导航条)
  4. Perl 中级教程 第5章课后习题
  5. gulimall(谷粒商城) 是一个综合性的B2C平台,包括前台商城系统以及后台管理系统
  6. oracle jinitiator 1.1.8.2,oracle jinitiator 1.1.8.2-Oracle Jinitiator1.1.8.27 3264位最新版下载_东坡手机下载...
  7. 如何对两个大型SQL Server数据库中的数据进行快速估计比较,以查看它们是否相等
  8. 2.73 交叉编译python_Python这么火,要不要学?听听华为工程师怎么说...
  9. mybatis的多AND条件查询。批量插入。String分割查询。
  10. LoadRunner 测试脚本
  11. 如何用Java的Robot完成模拟鼠标移动和键盘输入(可应用刷网课)
  12. cesium相机控制
  13. 功能测试的测试工作流程
  14. iOS SDK开发二三事
  15. 【Winform】 Enum逆向解析
  16. [音乐] 逆转裁判1~6【五分半无缝衔接】追求组曲
  17. pgsql装数卸数方案
  18. Postek博思得打印机
  19. 【即时通讯软件系统——开题报告 分享(仅供参考呀)】
  20. JavaScript红皮书学习笔记

热门文章

  1. JST-IOT-TPN三相宽带载波模块在物联网中的应用
  2. sonar常见扫描问题总结
  3. 论文阅读笔记《Sim-to-real learning for bipedal locomotion under unsensed dynamic loads》
  4. Depix 这款去“马赛克“工具效果如何?
  5. Spark解决 System memory 259522560 must be at least 471859200
  6. sCrypt 合约中的椭圆曲线算法:第一部分
  7. 中国家谱网:不同姓氏织成上下五千年的故事
  8. python 子网掩码长度和子网掩码地址转换
  9. 【Python游戏】可以实现双人对战游戏,类似拳皇可以选英雄的 绝对好玩 | 附带源码
  10. 为什么你使用程序化自动交易接口没有赚到钱?