mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
135 lines
4.0 KiB
Markdown
135 lines
4.0 KiB
Markdown
# [297. Serialize and Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/)
|
||
|
||
# 思路
|
||
对二叉树进行序列化和去序列化的操作。
|
||
|
||
## 思路一
|
||
本质上就是遍历二叉树,那我们考虑用递归前序遍历二叉树。
|
||
* 序列化:
|
||
* 如果节点为空则添加"# "(用空格作为分隔符,这样就可以用字符串流);
|
||
* 否则添加节点值(要紧跟一个空格)再递归进入左右孩子。
|
||
|
||
* 去序列化:
|
||
* 如果当前字符为"#",则返回空;
|
||
* 否则根据字符串的值新建节点,然后递归求其左右孩子。
|
||
|
||
我们可以用输入/输出字符串流`istringstream`/`ostringstream`来进行处理,详见代码。
|
||
|
||
## 思路二
|
||
我们还可以用非递归的层序遍历,这样就类似LeetCode使用的方法了。
|
||
|
||
* 序列化:
|
||
* 将根节点入队列,循环直到队列为空:出队首元素,若其为空则添加"# ";否则添加节点值(要紧跟一个空格),另外还要将其左右孩子入队(即使孩子为空)。
|
||
|
||
* 去序列化:
|
||
* 先处理得到根节点,然后将根节点入队,循环直到队列空:处理得到队首节点的左孩子,即将队首元素的左指针指向当前处理得到的节点,若这个左孩子不为空还要将其入队;再用类似的方法处理得到队首节点的右孩子;最后将队首元素出队。
|
||
|
||
同样用输入/输出字符串流`istringstream`/`ostringstream`来进行处理,详见代码。
|
||
|
||
本质都是遍历二叉树,所以两个思路时空复杂度均为O(n)
|
||
|
||
# C++
|
||
## 思路一
|
||
``` C++
|
||
class Codec {
|
||
private:
|
||
void serialize(TreeNode* root, ostringstream &out){
|
||
if(!root) out << "# ";
|
||
else{
|
||
out << root -> val << " ";
|
||
serialize(root -> left, out);
|
||
serialize(root -> right, out);
|
||
}
|
||
}
|
||
TreeNode* deserialize(istringstream &in){
|
||
string val;
|
||
in >> val;
|
||
if(val == "#") return NULL;
|
||
|
||
TreeNode *root = new TreeNode(stoi(val));
|
||
root -> left = deserialize(in);
|
||
root -> right = deserialize(in);
|
||
return root;
|
||
}
|
||
|
||
public:
|
||
|
||
// Encodes a tree to a single string.
|
||
string serialize(TreeNode* root) {
|
||
if(!root) return "";
|
||
ostringstream out;
|
||
serialize(root, out);
|
||
return out.str();
|
||
}
|
||
|
||
// Decodes your encoded data to tree.
|
||
TreeNode* deserialize(string data) {
|
||
if(!data.size()) return NULL;
|
||
|
||
istringstream in(data);
|
||
return deserialize(in);
|
||
}
|
||
};
|
||
```
|
||
|
||
## 思路二
|
||
``` C++
|
||
class Codec {
|
||
public:
|
||
// Encodes a tree to a single string.
|
||
string serialize(TreeNode* root) {
|
||
if(!root) return "";
|
||
ostringstream out;
|
||
|
||
TreeNode *p;
|
||
queue<TreeNode *>q;
|
||
q.push(root);
|
||
|
||
while(!q.empty()){
|
||
p = q.front(); q.pop();
|
||
if(!p) out << "# ";
|
||
else{
|
||
out << p -> val << " ";
|
||
q.push(p -> left);
|
||
q.push(p -> right);
|
||
}
|
||
}
|
||
return out.str();
|
||
}
|
||
|
||
// Decodes your encoded data to tree.
|
||
TreeNode* deserialize(string data) {
|
||
int len = data.size();
|
||
if(!len) return NULL;
|
||
|
||
queue<TreeNode *>q;
|
||
TreeNode *p = NULL, *root = NULL;
|
||
|
||
istringstream in(data);
|
||
string val;
|
||
|
||
// 根节点
|
||
in >> val;
|
||
p = new TreeNode(stoi(val)); root = p;
|
||
q.push(p);
|
||
|
||
while(!q.empty()){
|
||
in >> val; // 左孩子
|
||
if(val != "#"){
|
||
p = new TreeNode(stoi(val));
|
||
q.push(p);
|
||
q.front() -> left = p;
|
||
}
|
||
|
||
in >> val; // 右孩子
|
||
if(val != "#"){
|
||
p = new TreeNode(stoi(val));
|
||
q.push(p);
|
||
q.front() -> right = p;
|
||
}
|
||
q.pop();
|
||
}
|
||
return root;
|
||
}
|
||
};
|
||
``` |