297.Serialize-and-Deserialize-Binary-Tree
297. Serialize and Deserialize Binary Tree
题目地址
https://leetcode.com/problems/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.
代码
Approach 1: Depth First Search (DFS)
/**
* 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) {
return preorder(root, "");
}
public String preorder(TreeNode root, String str) {
if (root == null) {
str += "null,";
} else {
str += str.valueOf(root.val) + ",";
str = preorder(root.left, str);
str = preorder(root.right, str);
}
return str;
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
String[] data_array = data.split(",");
List<String> data_list = new LinkedList<String>(Arrays.asList(data_array));
return rdeserialize(data_list);
}
public TreeNode rdeserialize(List<String> l) {
if (l.get(0).equals("null")) {
l.remove(0);
return null;
}
TreeNode root = new TreeNode(Integer.valueOf(l.get(0)));
l.remove(0);
root.left = rdeserialize(l);
root.right = rdeserialize(l);
return root;
}
}
Approach #2 Iterative Preorder DFS
class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
Deque<TreeNode> stack = new LinkedList<>();
while (root != null || !stack.isEmpty()) {
if (root != null) {
sb.append(String.valueOf(root.val) + ",");
stack.push(root); // 压入已访问的root
root = root.left;
} else {
sb.append("null,");
root = stack.pop();
root = root.right;
}
}
return sb.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if (data.length() == 0) return null;
String[] data_array = data.split(",");
Queue<String> data_list = new LinkedList<String>(Arrays.asList(data_array));
Deque<TreeNode> stack = new LinkedList<>();
TreeNode root = new TreeNode(Integer.valueOf(data_list.poll()));
TreeNode x = root;
stack.push(x);
while (!data_list.isEmpty()) {
// left
while (!data_list.peek().equals("null")) {
x.left = new TreeNode(Integer.valueOf(data_list.poll()));
x = x.left;
stack.push(x); // 压入已访问的 x.left
}
// equal null
while (!data_list.isEmpty() && data_list.peek().equals("null")) {
x = stack.pop();
data_list.poll();
}
// right
if (!data_list.isEmpty()) {
x.right = new TreeNode(Integer.valueOf(data_list.poll()));
x = x.right;
stack.push(x);
}
}
return root;
}
}
Approach #3 BFS Preorder
class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if (root == null) return "";
Queue<TreeNode> q = new LinkedList<>();
StringBuilder sb = new StringBuilder();
q.offer(root);
sb.append(String.valueOf(root.val) + ",");
while (!q.isEmpty()) {
TreeNode node = q.poll();
if (node.left == null) {
sb.append("null,");
} else {
q.offer(node.left);
sb.append(String.valueOf(node.left.val) + ",");
}
if (node.right == null) {
sb.append("null,");
} else {
q.offer(node.right);
sb.append(String.valueOf(node.right.val) + ",");
}
}
return sb.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String str) {
if (str.length() == 0) return null;
String[] data_array = str.split(",");
Queue<String> data_list = new LinkedList<String>(Arrays.asList(data_array));
Queue<TreeNode> q = new LinkedList<>();
TreeNode root = new TreeNode(Integer.valueOf(data_list.poll()));
q.offer(root);
while (!q.isEmpty()) {
TreeNode node = q.poll();
// left
if (data_list.peek().equals("null")) {
node.left = null;
} else {
node.left = new TreeNode(Integer.valueOf(data_list.peek()));
q.offer(node.left);
}
data_list.poll();
// right
if (data_list.peek().equals("null")) {
node.right = null;
} else {
node.right = new TreeNode(Integer.valueOf(data_list.peek()));
q.offer(node.right);
}
data_list.poll();
}
return root;
}
}
Approach #3 Postorder traversal to optimise space for the tree structure
public class Codec {
public StringBuilder postorder(TreeNode root, StringBuilder sb) {
if (root == null) return sb;
postorder(root.left, sb);
postorder(root.right, sb);
sb.append(root.val);
sb.append(' ');
return sb;
}
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder sb = postorder(root, new StringBuilder());
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if (data.isEmpty()) return null;
ArrayDeque<Integer> nums = new ArrayDeque<Integer>();
for (String s : data.split("\\s+"))
nums.add(Integer.valueOf(s));
return helper(Integer.MIN_VALUE, Integer.MAX_VALUE, nums);
}
public TreeNode helper(Integer lower, Integer upper, ArrayDeque<Integer> nums) {
if (nums.isEmpty()) return null;
int val = nums.getLast();
if (val < lower || val > upper) return null;
nums.removeLast();
TreeNode root = new TreeNode(val);
root.right = helper(val, upper, nums);
root.left = helper(lower, val, nums);
return root;
}
}
Approach #3 Get rid of delimiters
public class Codec {
// Encodes a tree to a list.
public void postorder(TreeNode root, StringBuilder sb) {
if (root == null) return;
postorder(root.left, sb);
postorder(root.right, sb);
sb.append(intToString(root.val));
}
// Encodes integer to bytes string
public String intToString(int x) {
char[] bytes = new char[4];
for(int i = 3; i > -1; --i) {
bytes[3 - i] = (char) (x >> (i * 8) & 0xff);
}
return new String(bytes);
}
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
postorder(root, sb);
return sb.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
ArrayDeque<Integer> nums = new ArrayDeque<Integer>();
int n = data.length();
for(int i = 0; i < (int)(n / 4); ++i) {
nums.add(stringToInt(data.substring(4 * i, 4 * i + 4)));
}
return helper(Integer.MIN_VALUE, Integer.MAX_VALUE, nums);
}
// Decodes list to tree.
public TreeNode helper(Integer lower, Integer upper, ArrayDeque<Integer> nums) {
if (nums.isEmpty()) return null;
int val = nums.getLast();
if (val < lower || val > upper) return null;
nums.removeLast();
TreeNode root = new TreeNode(val);
root.right = helper(val, upper, nums);
root.left = helper(lower, val, nums);
return root;
}
// Decodes bytes string to integer
public int stringToInt(String bytesStr) {
int result = 0;
for(char b : bytesStr.toCharArray()) {
result = (result << 8) + (int)b;
}
return result;
}
}
Last updated