剑指 Offer 37. 序列化二叉树
题目描述
请实现两个函数,分别用来序列化和反序列化二叉树。
你需要设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
提示:输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
示例
输入:root = [1,2,3,null,null,4,5] 输出:[1,2,3,null,null,4,5]
思路
题目大体意思为让我们将一颗二叉树,根据我们自己设计的格式,转换成一个字符串,然后,根据这个字符串,再将树还原
由于题目没有限制序列化的格式,我这边采用的格式即为:
一个节点,之后跟着连续的两串字符,如果是,分别代表左节点和右节点,如果为 # ,则代表该节点为null,否则就为存在。如果一个节点存在,那么他紧接着又会跟着两串字符。序列的总体格式和先序遍历类似,只是加入了 # 作为标识符
即,假设一段序列:3 # 2 1 # # # 即为:根节点为3,然后接着一个 # 表示 3 的左节点为null , 之后的 2 表示 3 的右 节点为 2,再之后的 1 # 表示 2 的左节点为 1,右节点为null;最后的 # #代表1 的左右两个节点都为null
时间复杂度:O(n)
空间复杂度:O(n)
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
String st = "";
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if (root == null){
return "#";
}
st = "" + root.val;
ecode(root);
return st;
}
public void ecode(TreeNode p){
if (p.left == null){
st = st + " #";
}else {
st = st + " " + p.left.val;
ecode(p.left);
}
if (p.right == null){
st = st + " #";
}else {
st = st + " " + p.right.val;
ecode(p.right);
}
}
TreeNode head = null;
String data;
int l = 0, r = 0;
// Decodes your encoded data to tree.
public TreeNode deserialize(String data_) {
data = data_;
if (data.equals("#")){
return null;
}
l = 0; r = 0;
while(data.charAt(r) != ' '){
r++;
}
String s = data.substring(l, r);
head = new TreeNode(to_int(s));
l = r + 1; r = l;
dcode(head);
return head;
}
public int to_int(String s){
if (s.charAt(0) == '-'){
int ans = 0, len = s.length();
for (int i = 1; i < len; i++){
ans *= 10;
ans += s.charAt(i) - '0';
}
return -ans;
}else{
int ans = 0, len = s.length();
for (int i = 0; i < len; i++){
ans *= 10;
ans += s.charAt(i) - '0';
}
return ans;
}
}
public void dcode(TreeNode p){
if (data.charAt(l) == '#'){
l += 2; r += 2;
}else{
while (data.charAt(r) != ' '){
r++;
}
String s = data.substring(l, r);
p.left = new TreeNode(to_int(s));
l = r + 1; r = l;
dcode(p.left);
}
if (data.charAt(l) == '#'){
l += 2; r += 2;
}else{
while (data.charAt(r) != ' '){
r++;
}
String s = data.substring(l, r);
p.right = new TreeNode(to_int(s));
l = r + 1; r = l;
dcode(p.right);
}
}
}
// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// String tree = ser.serialize(root);
// TreeNode ans = deser.deserialize(tree);
// return ans;