请实现两个函数,分别用来序列化和反序列化二叉树.
比如这样的一棵二叉树
1
/ \
2 3
/ \ \
4 5 6
序列化结果为1 , 2 , 4 , $ , $ ,5 , $ , $ , 3 , $ , 6 , $ , $ (空指针用 $ 表示)
反序列化就是根据序列化的结果重构出这棵树
思路,首先就是要思考怎么样冲序列化的结果来重构出这棵树。想到用先序遍历方式,它以根节点开始,而构建一棵二叉树也是从根节点开始。
版本一:(搞笑版)
TreeNode hehe;
String Serialize(TreeNode root) {
hehe = root;
return "*^-^*";
}
TreeNode Deserialize(String str) {
return hehe;
}
这是我在讨论区看到一个大佬的o(1)复杂度的算法,简直了。。。。。但这个是利用了判题系统的bug。
版本二:O(N)
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
import java.lang.Integer;
public class Solution {
StringBuffer sb = new StringBuffer();
String Serialize(TreeNode root) {
if(root==null)
{
sb.append("$,");
return sb.toString();
}
sb.append(root.val+",");
Serialize(root.left);
Serialize(root.right);
return sb.toString();
}
int index = -1;
TreeNode Deserialize(String str) {
//关键在这个,index++,下一次就在下一个位置了
//这个重建的过程是先把左边的重建好了,再重建右边的
index++;
String[] strr = str.split(",");
TreeNode node = null;
if(!strr[index].equals("$"))
{
node = new TreeNode(Integer.valueOf(strr[index]));
node.left = Deserialize(str);
node.right = Deserialize(str);
}
return node;
}
}
这个是我的递归方式,这样只创建了一个StiringBuffer,但我看到有个老哥将对象创建放在了函数体里面,我觉得不是很好,那样子递归的值变化有点不一样。
public class Solution {
String Serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
if(root == null){
sb.append("#,");
return sb.toString();
}
sb.append(root.val + ",");
sb.append(Serialize(root.left));
sb.append(Serialize(root.right));
return sb.toString();
}
int index = -1;
TreeNode Deserialize(String str) {
index++;
//int len = str.length();
//if(index >= len){
// return null;
// }
String[] strr = str.split(",");
TreeNode node = null;
if(!strr[index].equals("#")){
node = new TreeNode(Integer.valueOf(strr[index]));
node.left = Deserialize(str);
node.right = Deserialize(str);
}
return node;
}
}
将StringBuilder sb = new StringBuilder();这一句放在递归体里面会导致,每次递归产生的是一个新对象,这样会创建很多对象,感觉不好,只是学一下这种思路,当在递归体创建对象的时候,要把返回的值加到父层的递归中。sb.append(Serialize(root.right)).
此外这道题最值得学习的是在反序列化中,采用index来不断取新的值。这样即使你在递归,但是我的取值一直往前走。