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

题目描述

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

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

提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

输入输出

1
2
3
4
5
6
7
8
9
10
11
输入:root = [1,2,3,null,null,4,5]
输出:[1,2,3,null,null,4,5]

输入:root = []
输出:[]

输入:root = [1]
输出:[1]

输入:root = [1,2]
输出:[1,2]

基本思路

序列化:在这个步骤中用null标记没有左右子节点了 结束递归

反序列化:需要根据把原先序列分隔开得到先序遍历的元素列表,然后从左到右遍历这个序列

  • 如果当前元素为null 则当前为空树
  • 否则先解析这棵树的左子树 再解析右子树

时复:序列化与反序列化都只访问节点一次 $O(n)$

空复:递归使用栈 $O(n)$

java实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Codec {

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

// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
String[] req = data.split(",");
//Arrays.asList 数组 -> 集合
ArrayList<String> res = new ArrayList<>(Arrays.asList(req));
return dfsdeserialize(res);
}

public TreeNode dfsdeserialize(ArrayList<String> r){
if("null".equals(r.get(0))){
r.remove(0);
return null;
}
TreeNode node = new TreeNode(Integer.valueOf(r.get(0)));
r.remove(0);
node.left = dfsdeserialize(r);
node.right = dfsdeserialize(r);
return node;
}
}

// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));