[LeetCode] 297. Serialize and Deserialize Binary Tree 二叉树的序列化和反序列化
Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
Example:
You may serialize the following tree:
1
/ \
2 3
/ \
4 5
as "[1,2,3,null,null,4,5]"
Clarification: The above format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
序列化是是指将数据结构或物件状态转换成可取用格式(例如存成档案,存于缓冲,或经由网络中传送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程,还原的过程叫做反序列化。比如例子中的把树序列化成数组,还可以由这个数组在反序列化变回树。
根据题目序列化的形式,可以先序遍历的递归或者层序遍历的非递归:
需要接入输入和输出字符串流istringstream和ostringstream,对于序列化,从根节点开始,如果节点存在,则将值存入输出字符串流,然后分别对其左右子节点递归调用序列化函数即可。对于反序列化,先读入第一个字符生成一个根节点,然后再对根节点的左右子节点递归调用去序列化函数即可。
Java:level order traversal
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if(root==null){
return "";
} StringBuilder sb = new StringBuilder(); LinkedList<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root);
while(!queue.isEmpty()){
TreeNode t = queue.poll();
if(t!=null){
sb.append(String.valueOf(t.val) + ",");
queue.add(t.left);
queue.add(t.right);
}else{
sb.append("#,");
}
} sb.deleteCharAt(sb.length()-1);
System.out.println(sb.toString());
return sb.toString();
} // Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data==null || data.length()==0)
return null; String[] arr = data.split(",");
TreeNode root = new TreeNode(Integer.parseInt(arr[0])); LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root); int i=1;
while(!queue.isEmpty()){
TreeNode t = queue.poll(); if(t==null)
continue; if(!arr[i].equals("#")){
t.left = new TreeNode(Integer.parseInt(arr[i]));
queue.offer(t.left); }else{
t.left = null;
queue.offer(null);
}
i++; if(!arr[i].equals("#")){
t.right = new TreeNode(Integer.parseInt(arr[i]));
queue.offer(t.right); }else{
t.right = null;
queue.offer(null);
}
i++;
} return root;
}
Java: Preorder traversal
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if(root==null)
return null; Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
StringBuilder sb = new StringBuilder(); while(!stack.isEmpty()){
TreeNode h = stack.pop();
if(h!=null){
sb.append(h.val+",");
stack.push(h.right);
stack.push(h.left);
}else{
sb.append("#,");
}
} return sb.toString().substring(0, sb.length()-1);
} // Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data == null)
return null; int[] t = {0};
String[] arr = data.split(","); return helper(arr, t);
} public TreeNode helper(String[] arr, int[] t){
if(arr[t[0]].equals("#")){
return null;
} TreeNode root = new TreeNode(Integer.parseInt(arr[t[0]])); t[0]=t[0]+1;
root.left = helper(arr, t);
t[0]=t[0]+1;
root.right = helper(arr, t); return root;
}
Java:
public class Codec {
private static final String spliter = ",";
private static final String NN = "X";
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
buildString(root, sb);
return sb.toString();
}
private void buildString(TreeNode node, StringBuilder sb) {
if (node == null) {
sb.append(NN).append(spliter);
} else {
sb.append(node.val).append(spliter);
buildString(node.left, sb);
buildString(node.right,sb);
}
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
Deque<String> nodes = new LinkedList<>();
nodes.addAll(Arrays.asList(data.split(spliter)));
return buildTree(nodes);
}
private TreeNode buildTree(Deque<String> nodes) {
String val = nodes.remove();
if (val.equals(NN)) return null;
else {
TreeNode node = new TreeNode(Integer.valueOf(val));
node.left = buildTree(nodes);
node.right = buildTree(nodes);
return node;
}
}
}
Python:
class Codec:
def serialize(self, root):
def serializeHelper(node):
if not node:
vals.append('#')
else:
vals.append(str(node.val))
serializeHelper(node.left)
serializeHelper(node.right)
vals = []
serializeHelper(root)
return ' '.join(vals)
def deserialize(self, data):
def deserializeHelper():
val = next(vals)
if val == '#':
return None
else:
node = TreeNode(int(val))
node.left = deserializeHelper()
node.right = deserializeHelper()
return node
def isplit(source, sep):
sepsize = len(sep)
start = 0
while True:
idx = source.find(sep, start)
if idx == -1:
yield source[start:]
return
yield source[start:idx]
start = idx + sepsize
vals = iter(isplit(data, ' '))
return deserializeHelper()
Python:
class Codec:
def serialize(self, root):
def doit(node):
if node:
vals.append(str(node.val))
doit(node.left)
doit(node.right)
else:
vals.append('#')
vals = []
doit(root)
return ' '.join(vals)
def deserialize(self, data):
def doit():
val = next(vals)
if val == '#':
return None
node = TreeNode(int(val))
node.left = doit()
node.right = doit()
return node
vals = iter(data.split())
return doit()
C++:
class Codec {
public:
string serialize(TreeNode* root) {
ostringstream out;
serialize(root, out);
return out.str();
}
TreeNode* deserialize(string data) {
istringstream in(data);
return deserialize(in);
}
private:
void serialize(TreeNode* root, ostringstream& out) {
if (!root) {
out << "# ";
return;
}
out << root->val << " ";
serialize(root->left, out);
serialize(root->right, out);
}
TreeNode* deserialize(istringstream& in) {
string val;
in >> val;
if (val == "#") return nullptr;
TreeNode* root = new TreeNode(stoi(val));
root->left = deserialize(in);
root->right = deserialize(in);
return root;
}
};
C++:
class Codec {
public:
string serialize(TreeNode* root) {
ostringstream out;
serialize(root, out);
return out.str();
}
TreeNode* deserialize(string data) {
istringstream in(data);
return deserialize(in);
}
private:
enum STATUS {
ROOT_NULL = 0x0,
ROOT = 0x1,
LEFT = 0x2,
RIGHT = 0x4
};
void serialize(TreeNode* root, ostringstream& out) {
char status = 0;
if (root) status |= ROOT;
if (root && root->left) status |= LEFT;
if (root && root->right) status |= RIGHT;
out.write(&status, sizeof(char));
if (!root) return;
out.write(reinterpret_cast<char*>(&(root->val)), sizeof(root->val));
if (root->left) serialize(root->left, out);
if (root->right) serialize(root->right, out);
}
TreeNode* deserialize(istringstream& in) {
char status;
in.read(&status, sizeof(char));
if (!status & ROOT) return nullptr;
auto root = new TreeNode(0);
in.read(reinterpret_cast<char*>(&root->val), sizeof(root->val));
root->left = (status & LEFT) ? deserialize(in) : nullptr;
root->right = (status & RIGHT) ? deserialize(in) : nullptr;
return root;
}
};
Followup: 如果是 n-ary怎么办?
All LeetCode Questions List 题目汇总
[LeetCode] 297. Serialize and Deserialize Binary Tree 二叉树的序列化和反序列化的更多相关文章
- 297 Serialize and Deserialize Binary Tree 二叉树的序列化与反序列化
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据.请设计一个算法来实现二叉树 ...
- 297. Serialize and Deserialize Binary Tree二叉树的序列化和反序列化(就用Q)
[抄题]: Serialization is the process of converting a data structure or object into a sequence of bits ...
- [leetcode]297. Serialize and Deserialize Binary Tree 序列化与反序列化二叉树
Serialization is the process of converting a data structure or object into a sequence of bits so tha ...
- [LeetCode] Serialize and Deserialize Binary Tree 二叉树的序列化和去序列化
Serialization is the process of converting a data structure or object into a sequence of bits so tha ...
- Leetcode 297. Serialize and Deserialize Binary Tree
https://leetcode.com/problems/serialize-and-deserialize-binary-tree/ Serialization is the process of ...
- [leetcode]297. Serialize and Deserialize Binary Tree一般二叉树的编解码
由于一般的前序遍历不能唯一的还原出原本你的二叉树,所以要改变一下: 记录二叉树的结构信息,也就是空节点用符号表示 一般的前序遍历只是记录了节点的前后顺序,通过记录空节点,每一层的结构就可以记录下来 解 ...
- 【LeetCode】297. Serialize and Deserialize Binary Tree 解题报告(Python)
[LeetCode]297. Serialize and Deserialize Binary Tree 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode ...
- LC 297 Serialize and Deserialize Binary Tree
问题: Serialize and Deserialize Binary Tree 描述: Serialization is the process of converting a data stru ...
- 【LeetCode】297. Serialize and Deserialize Binary Tree
二叉树的序列化与反序列化. 如果使用string作为媒介来存储,传递序列化结果的话,会给反序列话带来很多不方便. 这里学会了使用 sstream 中的 输入流'istringstream' 和 输出流 ...
随机推荐
- java代码转python代码
(1)安装工具(windows 环境下面) 先下载antlr: http://www.antlr3.org/download/antlr-3.1.3.tar.gz 链接:http://pan.baid ...
- Spring Cloud Eureka注册中心(快速搭建)
Spring Cloud 详解Eureka注册中心@(微服务)[java|spring-cloud|eureka] Eureka 注册中心是入门Spring Cloud微服务架构的必学组件,是学习所有 ...
- 最全 webpak4.0 打包性能优化清单
最全 webpak4.0 打包性能优化清单 webpack4.0如何进行打包优化? 无非是从两个角度进行优化,其一:优化打包速度,其二:优化打包体积,送你一份打包性能优化清单 1.使用loader的时 ...
- PHP隐藏IP地址末位的方法
很久之前写过一个使用ASP隐藏IP地址末位的文章,也就是有时候为了保护用户的隐私,会隐藏用户的IP地址,达成类似于 222.222.222.* 的效果. 现在想要用PHP来实现,经过尝试,其实非常简 ...
- python字符的表示格式
%% 百分号标记 #就是输出一个% %c 字符及其ASCII码%s 字符串%d 有符号整数(十进制)%u 无符号整数(十进制)%o 无符号整数(八进制)%x 无符号整数(十六进制)%X 无符号整数(十 ...
- crc计算工具推荐
比较好的crc计算工具,32位64位系统都可以用的.crc的校验方法也很多.推荐使用 下载地址
- C++报错:全局变量重定义或是多次定义
如何在C++中定义全局变量时避免重复定义呢? 只要在定义时尽量在.cpp文件中进行,而不要在.h 文件中定义,定义好了之后,可以在.h文件中利用extern关键字进行声明. 如果在.h文件中定义的话, ...
- L1141(bfs思想)
一,看 1,整个方格图其实可以看做是一些不连通的图. 当然图内部必然是联通的. 2,遍历的技巧没什么. 方格图入队的技巧..额,是这样的 int gtid(int x,int y) { return ...
- ssh2
UserBiz public interface UserBiz { public List<User> list(User user); public int add(User user ...
- Windbg命令的语法规则系列(一)
本文介绍使用调试器命令必须遵循的语法规则.使用Windbg调试时,应遵守以下一般语法规则: 您可以在命令和参数中使用大小写字母的任意组合,除非在本节的主题中特别指出. 可以用一个或多个空格或逗号(,) ...