题目信息
-
题目: 剑指 Offer 37. 序列化二叉树
-
时间: 2020-09-04
-
题目链接:Leetcode
-
tag:序列化 二叉树 队列
-
难易程度:中等
-
题目描述:
请实现两个函数,分别用来序列化和反序列化二叉树。
示例:
序列化为 “[1,2,3,null,null,4,5]”
解题思路
本题难点
题目要求的 “序列化” 和 “反序列化” 是 可逆 操作。因此,序列化的字符串应携带 “完整的” 二叉树信息,即拥有单独表示二叉树的能力。
具体思路
序列化的字符串实际上是二叉树的 “层序遍历”(BFS)结果。为使反序列化可行,考虑将越过叶节点后的 null 也看作是节点。
- **序列化 serialize **:借助队列,对二叉树做层序遍历,并将越过叶节点的 null 也打印出来。
- **反序列化 deserialize **:利用队列按层构建二叉树,借助一个指针 i 指向节点 node 的左、右子节点,每构建一个 node 的左、右子节点,指针 i 就向右移动 1 位。
代码
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| public class Codec {
public String serialize(TreeNode root) { if(root == null){ return "[]"; } Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); StringBuilder res = new StringBuilder("["); while(!queue.isEmpty()){ TreeNode node = queue.poll(); if(node != null){ res.append(node.val).append(","); queue.add(node.left); queue.add(node.right); }else{ res.append("null").append(","); } } res.deleteCharAt(res.length() - 1); res.append("]"); return res.toString(); }
public TreeNode deserialize(String data) { if(data == "[]"){ return null; } String[] value = data.substring(1,data.length() - 1).split(","); TreeNode root = new TreeNode(Integer.parseInt(value[0])); Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); int i = 1; while(!queue.isEmpty()){ TreeNode node = queue.poll(); if(!value[i].equals("null")){ node.left = new TreeNode(Integer.parseInt(value[i])); queue.add(node.left); } i++; if(!value[i].equals("null")){ node.right = new TreeNode(Integer.parseInt(value[i])); queue.add(node.right); } i++; } return root; } }
|
复杂度分析:
- 时间复杂度 O(N) : N 为二叉树的节点数,层序遍历需要访问所有节点,最差情况下需要访问 N+1 个 null ,总体复杂度为 O(2N+1)=O(N) 。
- 空间复杂度 O(N) : 最差情况下,队列 queue 同时存储 N+1/2个节点(或 N+1 个 null ),使用 O(N) ;列表 res 使用 O(N) 。
其他优秀解答
解题思路
我们可以根据前序遍历的顺序来序列化二叉树,因为前序遍历是从根节点开始的。在遍历二叉树碰到 null时,将其序列化为一个特殊的字符(如’$’),节点的数值之间要用一个特殊字符(如’,’)隔开,因为节点的值位数不定且正负不定。
代码
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 34 35 36 37 38 39 40
| int start=0; public String serialize(TreeNode root) { if(root==null) return "$"; StringBuilder res = new StringBuilder(); recur(root,res); return res.toString(); } public void recur(TreeNode root,StringBuilder res){ if(root==null){ res.append("$,"); return;} res.append(root.val); res.append(','); recur(root.left,res); recur(root.right,res); }
public TreeNode deserialize(String data) { if(data.equals("$")) return null; String inputs[] = data.split(","); return build(inputs); } public TreeNode build(String[] inputs){ TreeNode res; if(inputs[start].equals("$")){ start++; return null; } res = new TreeNode(Integer.parseInt(inputs[start])); start++; res.left = build(inputs); res.right = build(inputs); return res; } }
|