leetcode 297. Serialize and Deserialize Binary Tree
找工作面试的过程中碰见了一道出场率很高的面试题,在leetcode上有这道题,属于hard难度,leetcode297-实现二叉树的序列化和反序列化。用了两种方法,一种按层次(BFS)进行序列化和反序列化;另一种是按先序(DFS)进行序列化和反序列化
题目主要考察对树的遍历,以及如何根据一个输入序列构建一颗二叉树(如何构建二叉树),leetcode均测试通过。
方法一:按层次(BFS)序列化和反序列化。
package sgy.leetcodeTest;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
//节点的定义
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class Codec {
public static void main(String[] args) {
Codec codec = new Codec();
TreeNode root1 = codec.create();
TreeNode root2 = codec.deserialize(codec.serialize(root1));
codec.serialize(root2); //测试是否重建二叉树成功
}
//创建二叉树用于测试
//先序建立:"#" 表示 null
// 5 2 # # 3 2 3 # # 1 # # 4 # #
public TreeNode create() {
Scanner sc = new Scanner(System.in);
TreeNode root = null;
int val = 0;
String str = sc.next();
if (str.equals("#"))
root = null;
else {
val = Integer.parseInt(str);
root = new TreeNode(val);
root.left = create();
root.right = create();
}
return root;
}
//按层次BFS的序列化
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder res = new StringBuilder(); // 保存最终的结果
Queue<TreeNode> queue = new LinkedList<TreeNode>();
if (root == null)
return res.toString();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode cur = queue.poll();
if (cur != null) {
res.append(cur.val + " ");
queue.offer(cur.left); //左节点入队列
queue.offer(cur.right); //右节点入队列
} else {
res.append("# ");
}
}
System.out.println(res.toString().trim());
return res.toString().trim();
}
//反序列化
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if (data.length() == 0)
return null;
String[] str = data.split(" ");
TreeNode root = createTree(str);
return root;
}
//按层BFS的反序列化核心代码
//根据层遍历的反序列化是重做层遍历,遇到"#"就生成null节点,同时不把null节点放到队列里即可
public TreeNode createTree(String[] str) {
TreeNode root = null;
int index = 0;
root = createTreeNode(str[index++]);
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
TreeNode node = null;
while (!queue.isEmpty()) {
node = queue.poll();
node.left = createTreeNode(str[index++]);
node.right = createTreeNode(str[index++]);
if (node.left != null)
queue.offer(node.left);
if (node.right != null)
queue.offer(node.right);
}
return root;
}
public TreeNode createTreeNode(String str) {
if (str.equals("#"))
return null;
return new TreeNode(Integer.parseInt(str));
}
}
层次序列化测试截图,leetcode测试
方法二:通过先序遍历二叉树,实现二叉树的序列化和反序列化 。
//按先序DFS来序列化和反序列化
public String serialize(TreeNode root) {
StringBuilder res = new StringBuilder();
preOrder(root, res);
System.out.println(res.toString().trim());
return res.toString().trim();
}
public TreeNode deserialize(String data) {
if (data == null || data.length() == 0)
return null;
String[] str = data.split(" ");
int[] index = new int[]{0};
TreeNode root = reCreateTree(str, index);
return root;
}
public TreeNode reCreateTree(String[] str, int[] index) {
TreeNode root = null;
if (index[0] < str.length) {
int val = 0;
if (str[index[0]].equals("#")) {
return null;
} else {
val = Integer.parseInt(str[index[0]]);
root = new TreeNode(val);
index[0]++;
root.left = reCreateTree(str, index);
index[0]++;
root.right = reCreateTree(str, index);
}
}
return root;
}
public void preOrder(TreeNode root, StringBuilder res) {
if (root == null) {
res.append("# ");
return;
}
int val = root.val;
res.append(val + " ");
preOrder(root.left, res);
preOrder(root.right, res);
}
先序序列化及反序列化运行测试截图
转自:https://blog.youkuaiyun.com/baidu_22405691/article/details/52913175