算法题(程序员面试宝典)
解题思路主要来源于leetcode官方与《程序员面试宝典》。
297. 二叉树的序列化与反序列化
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
示例 1:
解题方法
前序遍历与后序遍历生成的序列都可进行反序列,因为可以找到其根节点。中序遍历生成的序列,因其根在序列间,无法确定其索引,因此中序遍历不可进行反序列操作。
解题思路1
前序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
sb.append("[");
serialize(root,sb);
sb.setCharAt(sb.length()-1,']');
//最终的格式为
return sb.toString();
}
public void serialize(TreeNode root,StringBuilder sb){
//base case
if(root==null){
sb.append("null").append(",");
return;
}
//前序遍历
sb.append(root.val).append(",");
serialize(root.left,sb);
serialize(root.right,sb);
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data.length()==0)
return null;
LinkedList<String> list = new LinkedList<>();
//substring 左闭右开
String newData = data.substring(1,data.length()-1);
//将字符存入LinkedList中
for(String s:newData.split(",")){
list.add(s);
}
return deserialize(list);
}
public TreeNode deserialize(LinkedList<String> list){
if(list.isEmpty())
return null;
String val = list.removeFirst();
int valNum;
if(val.equals("null")){
return null;
}
else{
valNum = Integer.parseInt(val);
}
TreeNode root = new TreeNode(valNum);
root.left = deserialize(list);
root.right = deserialize(list);
return root;
}
}
// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));
解题思路2
后序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
sb.append("[");
serialize(root,sb);
sb.setCharAt(sb.length()-1,']');
//最终的格式为[ , , , ]
return sb.toString();
}
public void serialize(TreeNode root,StringBuilder sb){
//base case
if(root==null){
sb.append("null").append(",");
return;
}
//后序遍历
serialize(root.left,sb);
serialize(root.right,sb);
sb.append(root.val).append(",");
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data.length()==0)
return null;
LinkedList<String> list = new LinkedList<>();
//substring 左闭右开
String newData = data.substring(1,data.length()-1);
//将字符存入LinkedList中
for(String s:newData.split(",")){
list.add(s);
}
return deserialize(list);
}
public TreeNode deserialize(LinkedList<String> list){
if(list.isEmpty())
return null;
//后序遍历 从后往前找根节点
String val = list.removeLast();
int valNum;
if(val.equals("null")){
return null;
}
else{
valNum = Integer.parseInt(val);
}
TreeNode root = new TreeNode(valNum);
root.right = deserialize(list);
root.left = deserialize(list);
return root;
}
}
// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));
解题思路3
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if(root==null)
return "";
StringBuilder sb = new StringBuilder();
sb.append("[");
serialize(root,sb);
sb.setCharAt(sb.length()-1,']');
//最终的格式为[ , , , ]
return sb.toString();
}
public void serialize(TreeNode root,StringBuilder sb){
//二叉树的层次遍历 借助队列
Queue<TreeNode> q = new LinkedList<TreeNode>();
//入队
q.offer(root);
//层次遍历框架
//当队列不为空
while(!q.isEmpty()){
//出队
TreeNode cur = q.poll();
//**层次遍历代码**
if(cur==null){
sb.append("null").append(",");
continue;
}else{
sb.append(cur.val).append(",");
}
//**************
q.offer(cur.left);
q.offer(cur.right);
}
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data.isEmpty())
return null;
LinkedList<String> list = new LinkedList<>();
//substring 左闭右开
String newData = data.substring(1,data.length()-1);
//将字符存入LinkedList中
for(String s:newData.split(",")){
list.add(s);
}
return deserialize(list);
}
public TreeNode deserialize(LinkedList<String> list){
if(list.isEmpty())
return null;
//队列用来存储父节点
TreeNode root = new TreeNode(Integer.parseInt(list.get(0)));
Queue<TreeNode> q = new LinkedList<TreeNode>();
q.offer(root);
//构建二叉树
for(int i=1;i<list.size();){
//队列中存的都是父节点
TreeNode parent = q.poll();
String left = list.get(i++);
if(left.equals("null")){
parent.left = null;
}else{
TreeNode leftNode = new TreeNode(Integer.parseInt(left));
parent.left = leftNode;
q.offer(leftNode);
}
String right = list.get(i++);
if(right.equals("null")){
parent.right = null;
}else{
TreeNode rightNode = new TreeNode(Integer.parseInt(right));
parent.right = rightNode;
q.offer(rightNode);
}
}
return root;
}
}
// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));