Leetcode: 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   5
as "[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.

参考Lintcode: http://www.cnblogs.com/EdwardLiu/p/4391418.html

不管是serialize还是deserialize都是做一个tree的level order traversal

serialize的时候遇到null节点,添加“#”到结果,但是不入队列

deserialize的时候遇到“#”,给cur treenode添加null的左child或右child,但是该child不入队列

我的方法都按照leetcode标准去掉了serialized末尾的“#”,deserialize的时候如果走到数组尾部但是queue非空,这时queue里所有节点都给它们add空的左右child

 

再次重申String值相等的比较是equals(), 不注意又写成==了,费了好多时间debug

 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         StringBuffer res = new StringBuffer();
16         LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
17         queue.offer(root);
18         res.append(root.val + " ");
19         while (!queue.isEmpty()) {
20             TreeNode cur = queue.poll();
21             TreeNode left = cur.left;
22             TreeNode right = cur.right;
23             if (left == null) {
24                 res.append("#" + " ");
25             }
26             else {
27                 res.append(left.val + " ");
28                 queue.offer(left);
29             }
30             if (right == null) {
31                 res.append("#" + " ");
32             }
33             else {
34                 res.append(right.val + " ");
35                 queue.offer(right);
36             }
37         }
38         if (res.charAt(res.length()-1) == ' ') res.deleteCharAt(res.length()-1);
39         int k = res.length()-1;
40         while (k>=0 && res.charAt(k)=='#') {
41             res.deleteCharAt(k);
42             res.deleteCharAt(k-1);
43             k -= 2;
44         }
45         return res.toString();
46     }
47 
48     // Decodes your encoded data to tree.
49     public TreeNode deserialize(String data) {
50         if (data==null || data.length()==0) return null;
51         String[] nodes = data.split(" ");
52         LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
53         TreeNode root = new TreeNode(Integer.parseInt(nodes[0]));
54         queue.offer(root);
55         int i = 1;
56         while (!queue.isEmpty() && i<nodes.length) {
57             TreeNode cur = queue.poll();
58             String left = nodes[i];
59             i++;
60             if (left.equals("#")) cur.left = null;
61             else {
62                 cur.left = new TreeNode(Integer.parseInt(left));
63                 queue.offer(cur.left);
64             }
65             if (i == nodes.length) break;
66             String right = nodes[i];
67             i++;
68             if (right.equals("#")) cur.right = null;
69             else {
70                 cur.right = new TreeNode(Integer.parseInt(right));
71                 queue.offer(cur.right);
72             }
73         }
74         while (!queue.isEmpty()) {
75             TreeNode cur = queue.poll();
76             cur.left = null;
77             cur.right = null;
78         }
79         return root;
80     }
81 }
82 
83 // Your Codec object will be instantiated and called as such:
84 // Codec codec = new Codec();
85 // codec.deserialize(codec.serialize(root));

 

Vote最高的PreOrder Traversal (Recursion)做法

本题别人用了双向队列 Deque, 注意23-24行,写的非常好

另外再注意一下29行的语法,nodes就是指向这个linkedlist的,所以linkedlist再怎么删,nodes始终指向linkedlist,而不是linkedlist的head,所以33-34行可以直接用nodes,而不需要考虑是不是要指向head的下一个

 1 public class Codec {
 2     private static final String spliter = ",";
 3     private static final String NN = "X";
 4 
 5     // Encodes a tree to a single string.
 6     public String serialize(TreeNode root) {
 7         StringBuilder sb = new StringBuilder();
 8         buildString(root, sb);
 9         return sb.toString();
10     }
11 
12     private void buildString(TreeNode node, StringBuilder sb) {
13         if (node == null) {
14             sb.append(NN).append(spliter);
15         } else {
16             sb.append(node.val).append(spliter);
17             buildString(node.left, sb);
18             buildString(node.right,sb);
19         }
20     }
21     // Decodes your encoded data to tree.
22     public TreeNode deserialize(String data) {
23         Deque<String> nodes = new LinkedList<>();
24         nodes.addAll(Arrays.asList(data.split(spliter)));
25         return buildTree(nodes);
26     }
27     
28     private TreeNode buildTree(Deque<String> nodes) {
29         String val = nodes.remove();
30         if (val.equals(NN)) return null;
31         else {
32             TreeNode node = new TreeNode(Integer.valueOf(val));
33             node.left = buildTree(nodes);
34             node.right = buildTree(nodes);
35             return node;
36         }
37     }
38 }

 

Follow Up:

如果已经知道这个Binary Tree的size为T, 怎么估计输出链表size?

答案是 2*T+1,    (假设tree perfect and complete, leaf node层有大概一半的node数,比之前所有层的node数之和还要多一,那么,最后一层node每个再派生两个“#”, 个数就会有T+1个,所以总共有2*T+1个)

转载于:https://www.cnblogs.com/EdwardLiu/p/5084538.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值