题目:
请实现两个函数,分别用来序列化和反序列化二叉树,不对序列化之后的字符串进行约束,但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。
二叉树的序列化(Serialize)是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树等遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#)
二叉树的反序列化(Deserialize)是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
例如,可以根据层序遍历的方案序列化,如下图:
层序序列化(即用函数Serialize转化)如上的二叉树转为"{1,2,3,#,#,6,7}",再能够调用反序列化(Deserialize)将"{1,2,3,#,#,6,7}"构造成如上的二叉树。
示例:
输入:{1,2,3,#,#,6,7}
返回值:{1,2,3,#,#,6,7}
思路:
序列化:将树转为字符串
层序遍历去转化,然后用StringBuilder去拼接,最后转成String
反序列化:将字符串转化成树
将字符串先变成字符串数组,除去多余的东西,再慢慢转成树
(这个过程一定要好好体会)
复杂度:
时间复杂度:遍历O(n)
空间复杂度:递归最差是O(n),一般为树高
代码:
String Serialize(TreeNode root) {
if(root == null) return "[]";
StringBuilder res = new StringBuilder();
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
res.append("{");
while(!queue.isEmpty()){
int len = queue.size();
for(int i=0;i<len;++i){
TreeNode node = queue.poll();
if(node!=null){
res.append(node.val+",");
queue.add(node.left);
queue.add(node.right);
}else res.append("#,");
}
}
//把最后一个逗号删除
res.deleteCharAt(res.length()-1);
res.append("]");
return res.toString();
}
TreeNode Deserialize(String str) {
if(str.equals("[]")) return null;
//先将头尾和逗号删除再转换成字符数组再转换成树
String vals[] = str.substring(1,str.length()-1).split(",");
//将字符串类型转成int
TreeNode res = new TreeNode(Integer.parseInt(vals[0]));
//还是用层序
Queue<TreeNode> queue = new LinkedList<>();
queue.add(res);
//用i遍历,很巧妙
int i = 1;
while(!queue.isEmpty()){
TreeNode node = queue.poll();
if(!vals[i].equals("#")){
node.left = new TreeNode(Integer.parseInt(vals[i]));
queue.add(node.left);
}
i++;
if(!vals[i].equals("#")){
node.right = new TreeNode(Integer.parseInt(vals[i]));
queue.add(node.right);
}
i++;
}
return res;
}