zoukankan      html  css  js  c++  java
  • [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.

    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.

    二叉树的序列化和反序列化。题目即是题意,序列化是需要把二叉树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 题目总结

  • 相关阅读:
    2019 SDN上机第2次作业
    2019 SDN上机第1次作业
    第07组 团队Git现场编程实战
    第二次结对编程作业
    c语言之问题集
    2019春第2次课程设计实验安排
    2019年十二周总结
    第十一周总结
    第十周作业
    第九周总结
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12453308.html
Copyright © 2011-2022 走看看