(虽然一眼知道怎么写,但是debug真是用了半天,难受,太菜了)
题目:
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
题解:
有两种
一种是字符串保存为 NULL 的节点,这样保留前序遍历的结果即可
还有一种不保存为 NULL 的节点,保留 前序 和 中序,然后推出这棵树
(当时想着练手,用第二种)
如果用第二种方法有几个小细节:
① 要保留各个节点的索引,因为有的不同节点值相同,这样如果在 前序 和 中序 中,则不知道是否是同一个值
② 不能保存为 “值 索引 值 索引 …” 这样可能匹配 "值 索引 ",匹配到一个莫名奇妙的 "索引 值 "(已踩坑)
③ string 相加,尽量避免 str = str1 + str2,效率很低,可以用 append
(这里有个很奇怪的点,str += str1 效率要比 str = str + str1,估计是运算符重载优化了性能)
代码如下,无难点:
class Codec {
public:
// Encodes a tree to a single string.
TreeNode* prev;
vector<pair<int, int> > temp1;
vector<pair<int, int> > temp2;
int flag = 0;
TreeNode* prep(TreeNode* v) {
if(v == NULL) return NULL;
TreeNode* t = new TreeNode(flag);
flag++;
t -> left = prep(v -> left);
t -> right = prep(v -> right);
return t;
}
void solve1(TreeNode* v, TreeNode* t) {
if(v == NULL) return;
temp1.push_back(make_pair(v -> val, t -> val));
solve1(v -> left, t -> left);
solve1(v -> right, t -> right);
}
void solve2(TreeNode* v, TreeNode* t) {
if(v == NULL) return;
solve2(v -> left, t -> left);
temp2.push_back(make_pair(v -> val, t -> val));
solve2(v -> right, t -> right);
}
string serialize(TreeNode* root) {
string res = "";
prev = prep(root);
solve1(root, prev);
solve2(root, prev);
for(int i = 0; i < temp1.size(); i++) {
res += to_string(temp1[i].first) + ' ' + to_string(temp1[i].second) + '!'; // 注意这里字符串拼接效率,不然真会超时
}
res = res + '?';
for(int i = 0; i < temp2.size(); i++) {
res += to_string(temp2[i].first) + ' ' + to_string(temp2[i].second) + '!'; // 注意这里字符串拼接效率,不然真会超时
}
return res;
}
// Decodes your encoded data to tree.
string str1 = "";
string str2 = "";
TreeNode* solve(string s1, string s2) {
if(s1 == "") return NULL;
int t = s1.find('!') + 1;
string val = s1.substr(0, t);
int flag = s2.find(val);
string s11, s21, s12, s22;
if(flag == 0) {
s11 = s21 = "";
}
else {
s11 = s1.substr(val.size(), flag);
s21 = s2.substr(0, flag);
}
if(val.size() + flag == s2.size()) {
s12 = s22 = "";
}
else {
s12 = s1.substr(val.size() + flag);
s22 = s2.substr(flag + val.size());
}
TreeNode* v = new TreeNode(atoi(val.substr(0, val.find(' ')).c_str()));
v -> left = solve(s11, s21);
v -> right = solve(s12, s22);
return v;
}
TreeNode* deserialize(string data) {
TreeNode* res;
int t = data.find('?');
str1 = data.substr(0, t);
str2 = data.substr(t + 1, t);
res = solve(str1, str2);
return res;
}
};