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

234 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目:给定一颗二叉树的根节点,要求将此二叉树进行序列化,二叉树序列化的含义是将二叉树存入一个连续的内存空间中。之后要求根据输入的序列化二叉树重构得到原来的二叉树。

解题思路

通过二叉树的序列化结果,是否我们可以想到二叉树的遍历,实际上二叉树的序列化就是将二叉树遍历一遍,这里序列化的答案和遍历一样并不是唯一的,序列化方式的不同会导致最后序列化的结果也不同,而不同的序列化结果则需要不同的反序列化方法。此处列举几种序列化方式:

  • 通过先序遍历来序列化
  • 通过中序遍历来序列化
  • 通过后序遍历来序列化
  • 通过层序遍历来序列化
  • 。。。。。。。。。。

以上是常见的遍历方式,我们可以根据这些遍历方式来进行序列化,下面演示二叉树的用先序遍历(使用递归实现)来进行二叉树的序列化:

// Encodes a tree to a single string.
public String serialize(TreeNode root) {
    if(root==null) return "#!";
    String res = root.val+"!";
    res += serialize(root.left);
    res += serialize(root.right);
    return res;
}

先序遍历的方式很简单,此处要注意的是在每个结点之后,我们需要拼上一个特殊的字符,为反序列化进行铺垫。

二叉树的反序列化首先需要将序列化的字符串进行拆分,此处就采用这个特殊字符拆分,由于先序遍历的特殊性,在拆分得到的数组中必然左边是左子树的结点,右边是右子树的结点,因此可以先处理左子树再处理右子树,此处可以用队列来存储所有的结点,每处理一个弹出一个即可,按照先序遍历的顺序再次重构此二叉树即可,代码如下:

// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
    Queue<String> queue = new ArrayDeque<>(Arrays.asList(data.split("!")));
    return deserialize(queue);
}

public TreeNode deserialize(Queue<String> queue){
    String value = queue.poll();
    if(value.equals("#")) return null;
    TreeNode node = new TreeNode(Integer.parseInt(value));
    node.left = deserialize(queue);
    node.right = deserialize(queue);
    return node;
}