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 search tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be serialized to a string and this string can be deserialized to the original tree structure. The encoded string should be as compact as possible. Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
So the first question is: what is the difference between this and #297?
This here is BST, however, in #297, it‘s BT. "The encoded string should be as compact as possible" here. The special property of binary search trees compared to general binary trees allows a more compact encoding. So while the solutions to problem #297 still work here as well, they‘re not as good as they should be.
For general BT, to reconstruct the tree, we need the information of both in-order and pre-order, or in-order and post-order. We‘ve practised that already.
However, as a BST, just the information of pre-order or post-order is sufficient to rebuild the tree.
The encoded string is also most compact, since we do not need to keep tract of information of ‘Null nodes‘.
Example: 4
2 6
1 3 5 7
The pre-order encoding is: "4213657". It is easy to tell "4" is root, "213" is left tree, "657" is right tree. We can use a Queue to implement this, very convenient.
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 public class Codec { 11 12 // Encodes a tree to a single string. 13 public String serialize(TreeNode root) { 14 if (root == null) return ""; 15 StringBuilder res = new StringBuilder(); 16 Stack<TreeNode> stack = new Stack<TreeNode>(); 17 TreeNode node = root; 18 while (!stack.isEmpty() || node!=null) { 19 if (node != null) { 20 res.append(node.val).append(" "); 21 stack.push(node); 22 node = node.left; 23 } 24 else { 25 node = stack.pop().right; 26 } 27 } 28 return res.toString().trim(); 29 } 30 31 // Decodes your encoded data to tree. 32 public TreeNode deserialize(String data) { 33 if (data==null || data.length()==0) return null; 34 String[] nodes = data.split(" "); 35 Queue<Integer> queue = new LinkedList<>(); 36 for (String node : nodes) { 37 queue.offer(Integer.valueOf(node)); 38 } 39 return buildTree(queue); 40 } 41 42 public TreeNode buildTree(Queue<Integer> queue) { 43 if (queue.isEmpty()) return null; 44 TreeNode root = new TreeNode(queue.poll()); 45 Queue<Integer> leftNodeVals = new LinkedList<>(); 46 while (!queue.isEmpty() && queue.peek()<=root.val) { 47 leftNodeVals.offer(queue.poll()); 48 } 49 root.left = buildTree(leftNodeVals); 50 root.right = buildTree(queue); 51 return root; 52 } 53 } 54 55 // Your Codec object will be instantiated and called as such: 56 // Codec codec = new Codec(); 57 // codec.deserialize(codec.serialize(root));