[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.

Clarification: The input/output 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.

Example 1:

Input: root = [1,2,3,null,null,4,5]
Output: [1,2,3,null,null,4,5]

Example 2:

Input: root = []
Output: []

Constraints:

  • The number of nodes in the tree is in the range [0, 104].
  • -1000 <= Node.val <= 1000

二叉树的序列化和反序列化。

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/serialize-and-deserialize-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目即是题意,序列化是需要把二叉树convert成一个字符串;同时这个字符串也可以被convert回对应的二叉树。影子题449题。这道题有两种思路,一种是BFS层序遍历,一种是preorder前序遍历。

首先是BFS。序列化的部分是按照level order traversal的思路遍历树的节点。如果当前节点为NULL则存入"null";若不是,则正常存入当前节点,再遍历当前节点的左孩子和右孩子。记得存入每个节点之后加一个空格,这样方便接下来的反序列。

反序列化是将一个字符串的input转换成树的结构。首先将字符串中第一个node拿到,当做根节点。之后还是根据BFS的思路遍历input,如果不为"null"则做成一个节点并加入queue;但是这里反序列化可以跳过null,不需要把null也转换成一个空的节点放入二叉树。

时间O(n)

空间O(n)

Java实现

 1 public class Codec {
 2 
 3     // Encodes a tree to a single string.
 4     public String serialize(TreeNode root) {
 5         if (root == null)
 6             return "";
 7         StringBuilder res = new StringBuilder();
 8         Queue<TreeNode> queue = new LinkedList<>();
 9         queue.offer(root);
10         while (!queue.isEmpty()) {
11             TreeNode cur = queue.poll();
12             if (cur == null) {
13                 res.append("null ");
14                 continue;
15             }
16             res.append(cur.val + " ");
17             queue.offer(cur.left);
18             queue.offer(cur.right);
19         }
20         return res.toString();
21     }
22 
23     // Decodes your encoded data to tree.
24     public TreeNode deserialize(String data) {
25         if (data == "")
26             return null;
27         String[] str = data.split(" ");
28         TreeNode root = new TreeNode(Integer.parseInt(str[0]));
29         Queue<TreeNode> queue = new LinkedList<>();
30         queue.offer(root);
31         for (int i = 1; i < str.length; i++) {
32             TreeNode cur = queue.poll();
33             if (!str[i].equals("null")) {
34                 cur.left = new TreeNode(Integer.parseInt(str[i]));
35                 queue.offer(cur.left);
36             }
37             i++;
38             if (!str[i].equals("null")) {
39                 cur.right = new TreeNode(Integer.parseInt(str[i]));
40                 queue.offer(cur.right);
41             }
42         }
43         return root;
44     }
45 }
46 
47 // Your Codec object will be instantiated and called as such:
48 // Codec codec = new Codec();
49 // codec.deserialize(codec.serialize(root));

 

JavaScript实现

 1 /**
 2  * Encodes a tree to a single string.
 3  *
 4  * @param {TreeNode} root
 5  * @return {string}
 6  */
 7 var serialize = function (root) {
 8     let stack = [];
 9     let serialize = [];
10     if (root == null) return [];
11     stack.push(root);
12     while (stack.length > 0) {
13         let cur = stack.shift();
14         serialize.push(cur ? cur.val : null);
15         if (cur != null) {
16             stack.push(cur.left);
17             stack.push(cur.right);
18         }
19     }
20     return serialize;
21 };
22 
23 var deserialize = function (data) {
24     if (data[0] == null) return null;
25     let node = new TreeNode(data.shift());
26     let queue = [node];
27     while (queue.length > 0) {
28         let node = queue.shift();
29         left = data.shift();
30         right = data.shift();
31         node.left = (left == null) ? null : new TreeNode(left);
32         node.right = (right == null) ? null : new TreeNode(right);
33         if (node.left != null) {
34             queue.push(node.left);
35         }
36         if (node.right != null) {
37             queue.push(node.right);
38         }
39     }
40     return node;
41 };
42 
43 /**
44  * Your functions will be called as such:
45  * deserialize(serialize(root));
46  */

 

再来是前序遍历的思路。既然是前序遍历,那么还是先处理当前节点,再处理他的左孩子和右孩子。序列化的部分,还是需要对空节点记录,我这里还是记录成"null" + 一个空格,然后调用helper函数递归处理左孩子和有孩子。反序列化的时候,除了一开始需要把data分开,同时需要把data分开的内容放入一个queue,这样每弹出一个元素,我们还是可以通过一个helper函数递归处理左孩子和右孩子节点。这个做法比之前BFS的做法稍稍快一点。

时间O(n)

空间O(n)

Java实现

 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         StringBuilder sb = new StringBuilder();
15         helper(root, sb);
16         return sb.toString();
17     }
18 
19     private void helper(TreeNode root, StringBuilder sb) {
20         if (root == null) {
21             // sb.append("#").append(",");
22             sb.append("null ");
23         } else {
24             sb.append(root.val).append(" ");
25             helper(root.left, sb);
26             helper(root.right, sb);
27         }
28     }
29 
30     // Decodes your encoded data to tree.
31     public TreeNode deserialize(String data) {
32         // corner case
33         if (data == null) {
34             return null;
35         }
36         // normal case
37         String[] strs = data.split(" ");
38         Queue<String> queue = new LinkedList<>();
39         Collections.addAll(queue, strs);
40         return helper(queue);
41     }
42 
43     private TreeNode helper(Queue<String> queue) {
44         if (queue.isEmpty()) {
45             return null;
46         }
47         String s = queue.poll();
48         if (s.equals("null")) {
49             return null;
50         }
51         TreeNode root = new TreeNode(Integer.parseInt(s));
52         root.left = helper(queue);
53         root.right = helper(queue);
54         return root;
55     }
56 }
57 
58 // Your Codec object will be instantiated and called as such:
59 // Codec ser = new Codec();
60 // Codec deser = new Codec();
61 // TreeNode ans = deser.deserialize(ser.serialize(root));

 

相关题目

297. Serialize and Deserialize Binary Tree

428. Serialize and Deserialize N-ary Tree

449. Serialize and Deserialize BST

LeetCode 题目总结

posted @ 2020-03-10 03:54  CNoodle  阅读(217)  评论(0编辑  收藏  举报