心情
春天来的时候,总觉得会发生点什么,但是到头来,什么都没发生,然后就觉得自己错过了点什么。
——《立春》
读题
leetcode: 297. 二叉树的序列化与反序列化
描述:
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
不要使用类的成员 / 全局 / 静态变量来存储状态,你的序列化和反序列化算法应该是无状态的。
实际上考的是二叉树的遍历。这个大学时候讲过:前序遍历(中左右)、中序遍历(左中右)、后续遍历(左右中)。这道题中还有一个层次遍历的概念。
思路
1:几种遍历方法都差不多,故选了前序遍历的方法。
2:树一般都使用递归的思路来实现。
实现
public class Codec {
public String serialize(TreeNode root) {
//按照前序遍历,将树转为字符串
String result = "";
if (root != null) {
result = tree2String(root);
result = result.substring(0, result.length() - 1);
}
return result;
}
/**
* 前序遍历的序列化
* @param root 节点
* @return 已拼接的字符串
*/
public String tree2String(TreeNode root) {
String str = "";
if (root == null) {
str += "x,";
} else {
str += root.val + ",";
str += tree2String(root.left);
str += tree2String(root.right);
}
return str;
}
public TreeNode deserialize(String data) {
if (data == null || data.length() == 0) {
return null;
}
String[] strs = data.split(",");
TreeNode node = new TreeNode(Integer.valueOf(strs[0]));
string2Tree(node, strs, 0);
return node;
}
/**
* 前序遍历的反序列化
* @param node 当前节点
* @param strs 序列化结果
* @param i 指针
* @return 指针
*/
public int string2Tree(TreeNode node, String[] strs, int i) {
if (i < strs.length) {
//处理左节点
i++;
if (!"x".equals(strs[i])) {
node.left = new TreeNode(Integer.valueOf(strs[i]));
i = string2Tree(node.left, strs, i);
}
//处理右节点
i++;
if (!"x".equals(strs[i])) {
node.right = new TreeNode(Integer.valueOf(strs[i]));
i = string2Tree(node.right, strs, i);
}
}
//返回指针
return i;
}
}
提交
感觉还行,其他几种遍历方式就不尝试了,大抵上是差不多的。
特别的思路
官方题解
用括号来包裹子树的序列化,最终的模式:(T) num (T)
num为当前节点的值,左侧T为左子树序列化,右侧T为右子树序列化,也采用括号包裹的方式。
这种方法让我想起了检测成对括号的方法,在spring检测占位符时,就有检测成对括号的方法。简而言之递归吧。