描述
请实现两个函数,分别用来序列化和反序列化二叉树,不对序列化之后的字符串进行约束,但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。
二叉树的序列化(Serialize)是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树等遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#)
二叉树的反序列化(Deserialize)是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
例如,可以根据层序遍历的方案序列化,如下图:
层序序列化(即用函数Serialize转化)如上的二叉树转为"{1,2,3,#,#,6,7}",再能够调用反序列化(Deserialize)将"{1,2,3,#,#,6,7}"构造成如上的二叉树。
当然你也可以根据满二叉树结点位置的标号规律来序列化,还可以根据先序遍历和中序遍历的结果来序列化。不对序列化之后的字符串进行约束,所以欢迎各种奇思妙想。
数据范围:节点数 n \le 100n≤100,树上每个节点的值满足 0 \le val \le 1500≤val≤150
要求:序列化和反序列化都是空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
示例1
输入:{1,2,3,#,#,6,7}
返回值:{1,2,3,#,#,6,7}
说明:
如题面图
示例2
输入:{8,6,10,5,7,9,11}
返回值:{8,6,10,5,7,9,11}
第一种解法
序列化的时候,参考第六十题,把二叉树按照顺序打印成多行,按,分割,反序列化的时候,按照,分割,借助队列来实现,具体代码如下
String firstSerialize(TreeNode root) {
List<String> list = new ArrayList<>();
if(root == null){
return list.toString();
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()){
TreeNode<Integer> poll = queue.poll();
if(poll == null){
list.add("#");
continue;
}
list.add(poll.val+"");
queue.add(poll.left);
queue.add(poll.right);
}
String collect = list.stream().collect(Collectors.joining(","));
return collect;
}
TreeNode firstDeserialize(String str) {
if(str.equals("[]")){
return null;
}
String[] split = str.split(",");
int i = 0;
TreeNode treeNode = new TreeNode(split[i]);
Queue<TreeNode> queue = new LinkedList<>();
queue.add(treeNode);
i++;
while (i < split.length){
TreeNode poll = queue.poll();
if(!split[i].equals("#")){
TreeNode treeNodeLeft = new TreeNode(Integer.valueOf(split[i]));
poll.left = treeNodeLeft;
queue.add(treeNodeLeft);
}
i++;
if(!split[i].equals("#")){
TreeNode treeNodeRight = new TreeNode(Integer.valueOf(split[i]));
poll.right = treeNodeRight;
queue.add(treeNodeRight);
}
i++;
}
return treeNode;
}
第二种解法
序列化的时候,不按照顺序遍历,按照先序,中序,或者后序来进行序列化,反序列化的时候,按照先序顺利还原即可,代码如下
private String secondSerialize(TreeNode root) {
List<String> list = new ArrayList<>();
if(root == null){
return list.toString();
}
dlr(root,list);
String collect = list.stream().collect(Collectors.joining(","));
return collect;
}
private void dlr(TreeNode root,List<String> list){
if (root != null){
list.add(root.val+"");
dlr(root.left,list);
dlr(root.right,list);
}else {
list.add("#");
}
}
TreeNode secondDeserialize(String str) {
if(str.equals("[]")){
return null;
}
String[] split = str.split(",");
List<String> list = new ArrayList<String>(Arrays.asList(split));
return rDeserialize(list);
}
private TreeNode rDeserialize(List<String> list){
if (list.get(0).equals("#") || list.get(0) == "#"){
list.remove(0);
return null;
}
TreeNode treeNode = new TreeNode(Integer.valueOf(list.get(0)));
list.remove(0);
treeNode.left = rDeserialize(list);
treeNode.right = rDeserialize(list);
return treeNode;
}