[LeetCode] 297. 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.
For example, you may serialize the following tree
1 / \ 2 3 / \ 4 5as
"[1,2,3,null,null,4,5]"
, just the same as how LeetCode OJ 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.
Thought process:
Do a preorder traversal on the tree. Use a StringBuilder to serialize the nodes. When deserializing, use a queue to pop nodes in the correct order.
Solution 1( preorder traversal):
Level-order traversal:
Do a preorder traversal on the tree. Use a StringBuilder to serialize the nodes. When deserializing, use a queue to pop nodes in the correct order.
Solution 1( preorder traversal):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | /** * 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(); serialize(root, sb); return sb.deleteCharAt(sb.length() - 1).toString(); } private void serialize(TreeNode node, StringBuilder sb) { if (node == null) { sb.append("n,"); return; } sb.append(node.val + ","); serialize(node.left, sb); serialize(node.right, sb); } // Decodes your encoded data to tree. public TreeNode deserialize(String data) { Queue<String> queue = new LinkedList<>(); queue.addAll(Arrays.asList(data.split(","))); return deserialize(queue); } private TreeNode deserialize(Queue<String> queue) { String s = queue.poll(); if (s.equals("n")) { return null; } TreeNode node = new TreeNode(Integer.parseInt(s)); node.left = deserialize(queue); node.right = deserialize(queue); return node; } } // Your Codec object will be instantiated and called as such: // Codec codec = new Codec(); // codec.deserialize(codec.serialize(root)); |
Level-order traversal:
- Serialize: BFS the tree. Once a node is put into the queue, it's ensured that its two children will also be iterated.
- Deserialize: parse the string node by node. If I come across an actual node, put it in a queue. Every subsequent pair of nodes is the children of the first node in queue.
Solution 2 (level-order traversal):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | /** * 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) { Queue<TreeNode> queue = new LinkedList<>(); StringBuilder sb = new StringBuilder(); if (root == null) { return ""; } queue.offer(root); while (!queue.isEmpty()) { TreeNode node = queue.poll(); if (node == null) { sb.append(",null"); } else { sb.append("," + node.val); queue.offer(node.left); queue.offer(node.right); } } return sb.deleteCharAt(0).toString(); } // Decodes your encoded data to tree. public TreeNode deserialize(String data) { if (data.length() == 0) { return null; } String[] nodes = data.split(","); Queue<TreeNode> queue = new LinkedList<>(); TreeNode root = new TreeNode(Integer.parseInt(nodes[0])); queue.offer(root); int i = 1; while (!queue.isEmpty()) { TreeNode parent = queue.poll(); if (nodes[i].equals("null")) { parent.left = null; } else { TreeNode left = new TreeNode(Integer.parseInt(nodes[i])); parent.left = left; queue.offer(left); } i++; if (nodes[i].equals("null")) { parent.right = null; } else { TreeNode right = new TreeNode(Integer.parseInt(nodes[i])); parent.right = right; queue.offer(right); } i++; } return root; } } // Your Codec object will be instantiated and called as such: // Codec codec = new Codec(); // codec.deserialize(codec.serialize(root)); |
Time complexity: both are O(n).
Comments
Post a Comment