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;
}