[JavaScript 刷题] 树 - 二叉树的序列化与反序列化, leetcode 297

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JavaScript 刷题] 树 - 二叉树的序列化与反序列化, leetcode 297相关的知识,希望对你有一定的参考价值。

[javascript 刷题] 树 - 二叉树的序列化与反序列化, leetcode 297

github repo 地址: https://github.com/GoldenaArcher/js_leetcode,Github 的目录 大概 会更新的更勤快一些。

题目地址:297. Serialize and Deserialize Binary Tree

题目

如下:

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.

Clarification: The input/output format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.

解题思路

是一个序列化和反序列化的操作,题目中要求始说:

You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.

即,二叉树需要被序列化成字符串,同时也要能被反序列化出来。不过 leetcode 好像没怎么测试中间的实现是通过字符串还是通过数组完成的……

总体上来说就是两个大方向,DFS+前序遍历 和 BFS+层级遍历 的方式去解决。不了解四种遍历方式的可以参考 二叉树先序、中序、后序及层次四种遍历

下面的案例用的都是题目中的图:

BFS

  • 序列化过程

    使用 queue 解决问题,另外使用一个数组保存遍历的值。开始时将根节点推入 queue 中,queue 为:[1],res 的值为 []

    当扫描第一层时,进行 dequeue 操作后将 [1] 的左右子树推入 queue 中,queue 为:[2, 3],res 的值为 [1]

    同样进行 dequeue 操作后,这一层会有两个结点:232 的左右子树均为空,不过还是需要将它的左右子树推入 queue 中。queue 为:[null, null, 4, 5],res 的值为 [1, 2, 3]

    这一层在 dequeue 后所获得的值包含两个 null,如果是 null 的话就跳过,继续进行下一步的处理。queue 为 4 个 null 值,res 的值为 [1, 2, 3, null, null, 4, 5]

    最后一步则是重复步骤,将最后几个 null 推入 res 中。最终 res 的值为:[1, 2, 3, null, null, 4, 5, null, null, null, null],最终将其输出为字符串即可。

  • 反序列化过程

    反序列化过程与序列化过程一致,第一个值为 root(1),随后就是每一层推进。

    1 的左右结点为 23,第二层推进完毕。

    2 的子节点为空,空结点不推入 queue 中,随后处理 3,如此按顺进行即可。

DFS

前序遍历所要做的就是一直将当前结点进行输出,随后将所有左子树进行输出,再将所有右子树进行输出,题目则是可以查看 leetcode 144. Binary Tree Preorder Traversal。

该题使用递归完成较为简单,直接查看代码食用比较便于理解。

使用 JavaScript 解题

BFS 解法

var serialize = function (root) 
  const reserialize = (root, res) => 
    if (!root) return res.push(null);

    res.push(root.val);
    reserialize(root.left, res);
    reserialize(root.right, res);
  ;

  const res = [];

  reserialize(root, res);

  return res.join(",");
;

var deserialize = function (data) 
  const list = data.split(",");

  const redeserialize = (list) => 
    if (!list.length || list[0] === "") 
      list.shift();
      return null;
    

    const root = new TreeNode(list.shift());
    root.left = redeserialize(list);
    root.right = redeserialize(list);

    return root;
  ;

  return redeserialize(list);
;

DFS 解法

基本上就是完全套用 144 题的解决方案,总体来说,使用递归的代码会简单很多,但是需要考虑是否会碰到 stack overflow 的问题。

var serialize = function (root) 
  const reserialize = (root, res) => 
    if (!root) return res.push(null);

    res.push(root.val);
    reserialize(root.left, res);
    reserialize(root.right, res);
  ;

  const res = [];

  reserialize(root, res);

  return res.join(",");
;

var deserialize = function (data) 
  const list = data.split(",");

  const redeserialize = (list) => 
    if (!list.length || list[0] === "") 
      list.shift();
      return null;
    

    const root = new TreeNode(list.shift());
    root.left = redeserialize(list);
    root.right = redeserialize(list);

    return root;
  ;

  return redeserialize(list);
;

以上是关于[JavaScript 刷题] 树 - 二叉树的序列化与反序列化, leetcode 297的主要内容,如果未能解决你的问题,请参考以下文章

[JavaScript 刷题] 树 - 二叉树的序列化与反序列化, leetcode 297

二叉树面试题刷题模板(终极版)

万字长文!二叉树入门和刷题看这篇就够了!

二叉树刷题篇(11) 二叉搜索树的最小绝对差与众数

二叉树刷题篇平衡二叉树与二叉树的所有路径

二叉树刷题篇(完) 二叉搜索树的修剪构造与转换