题目
请实现两个函数,分别用来序列化和反序列化二叉树。
示例:
解题思路
序列化:其实就是把二叉树用字符串表示出来,可以考虑使用二叉树的遍历:前序,中序,后序,层次
这里我们使用前序遍历,即根左右的顺序
- 创建一个list,用来保存前序遍历的结果
- 前序遍历
- 判断当前是否为空,为空则添加null字符串,直接返回
- 添加当前节点的值
- 递归左子树
- 递归右子树
- 把list转换成字符串返回
反序列化:其实就是依据字符串创建二叉树,使用和序列化时相同的方式即可
- 对字符串进行校验
- 把字符串切割,创建一个字符串队列
- 前序遍历
- 判断当前队列是否为空,为空直接返回null
- 出队一个元素,如果为字符串null,直接返回null
- 如果不是,则构建当前节点
- 递归构建左子树
- 递归构建右子树
- 返回当前节点
- 返回当前节点
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
// 创建一个list,用来存储序列化结果
List<String> list = new ArrayList<>();
dfs(root, list);
return String.join(",", list);
}
private void dfs(TreeNode node, List<String> list) {
// 递归结束条件
if (node == null) {
list.add("null");
return;
}
// 二叉树的先序遍历,根左右
list.add(String.valueOf(node.val));
dfs(node.left, list);
dfs(node.right, list);
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
// 字符串校验
if (data == null || data.isEmpty()) {
return null;
}
//把字符串切割,转换成一个队列
LinkedList<String> list = new LinkedList<>(Arrays.asList(data.split(",")));
return dfs(list);
}
private TreeNode dfs(LinkedList<String> list) {
// 当前队列为空时,直接返回null
if (list.isEmpty()) {
return null;
}
// 出队
String s = list.poll();
// 约定的空节点字符串
if (s.equals("null")) {
return null;
}
// 构建也是使用先序遍历的顺序
TreeNode node = new TreeNode(Integer.parseInt(s));
node.left = dfs(list);
node.right = dfs(list);
return node;
}
}
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));
复杂度
- 时间复杂度:O(n),极端情况下,二叉树退化成链表,前序遍历递归n层
- 空间复杂度:O(n),使用list存储前序遍历中间结果