题目链接:https://leetcode.cn/problems/serialize-and-deserialize-bst/
题目大意:给出一颗二叉搜索树,要求以任意方式将其序列化和反序列化。也就是以任意方式将其转化为一个string
并且在输入string
后能将其还原出来。
思路:正常选一种遍历方式将其编码再解码就好。但一开始我犯了一个错误,因为返回的string
中如果全是数字,是不知道如何做分隔的,比如123
到底是1 2 3
还是12 3
是不知道的,因此我在类中加了一个成员vector<int> len
用于记录每段的长度。但后来发现不行。因为调用的方式,根据题目所述,是这样的:
Codec* ser = new Codec();
Codec* deser = new Codec();
string tree = ser->serialize(root);
TreeNode* ans = deser->deserialize(tree);
return ans;
也就是说,编码器和解码器是【同一个类的】【两个不同的对象】,这也符合常理。因为题目说了,可能是把这个二叉树编码后,传递到另外一台电脑上,让另外一台电脑做解码。此时由于两台电脑上的Codec
是两个不同的对象,它们是无法共享len
的,因此无法完成解码工作。
于是【分隔】的工作要在string
里直接完成,一个可行的方法是在每个数字中间插入一个分隔符。(但由于题目中说了要求字符串尽可能紧凑,我一开始认为加分隔符是不被允许的…)
完整代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
void DFS(TreeNode* node, string& data) {
if (!node)
return;
string tmp = to_string(node->val);
data += tmp;
data += ",";
if (node->left)
DFS(node->left, data);
if (node->right)
DFS(node->right, data);
}
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string data = "";
DFS(root, data);
return data;
}
TreeNode* decode(vector<string>& nums, int start, int end) {
if (end < start)
return nullptr;
int rv = stoi(nums[start]);
TreeNode* parent = new TreeNode(rv);
int idx;
for (idx = start+1; idx <= end; idx++) {
if (stoi(nums[idx]) > rv)
break;
}
if (idx > end) {
parent->left = decode(nums, start+1, end);
parent-> right = nullptr;
}
else {
parent->left = decode(nums, start+1, idx-1);
parent->right = decode(nums, idx, end);
}
return parent;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
vector<string> nums;
int pos = 0, rear;
while (pos < data.length()) {
rear = pos+1;
while (rear < data.length()) {
if (data[rear] == ',')
break;
rear++;
}
nums.push_back(data.substr(pos, rear-pos));
pos = rear+1;
}
return decode(nums, 0, nums.size()-1);
}
};
// 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;