Binary Tree Serialization

This question is very important:

1) Serialization: 

a. Don't try to do all the things at once. The first step is to get a list of all the tree node. The second step is to remove the null nodes in the end. The last step is to convert it to String. http://www.jiuzhang.com/solution/binary-tree-serialization

b. The middle null need to be pushed into the list. Otherwise, you couldn't track "#"

c. We can use queue to process this question, but it is not the best way, it mixed the step 1 and 2 together. 

2) Deserialization:

a. In order to link the parent children nodes, we need to keep tracking the parent's index

Way 1: We can use the index relationship: left = 2 * parent + 1 || right = 2 * parent + 2 ==> parent = (children - 1) / 2  parent start from zero

Way 2: We keep a flag isLeft. Initially it is set to "true", and rotated to set to !isLeft. Before rotated, if isLeft is set to "false", we need to increase parent's index. 

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */
class Solution {
    /**
     * This method will be invoked first, you should design your own algorithm 
     * to serialize a binary tree which denote by a root node to a string which
     * can be easily deserialized by your own "deserialize" method later.
     */
    
    public String serialize(TreeNode root) {
        // write your code here
        StringBuilder rstBuffer = new StringBuilder();
        rstBuffer.append('{');
        if (root == null) {
            return rstBuffer.append('}').toString();
        }
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        q.offer(root);
        while (!q.isEmpty()) {
            StringBuilder level = new StringBuilder();
            int n = q.size();
            for (int i = 0; i < n; i++) {
                TreeNode cur = q.poll();
                if (cur == null) {
                    level.append("#");
                    level.append(",");
                } else {
                    level.append(cur.val);
                    level.append(",");
                    q.offer(cur.left);
                    q.offer(cur.right);
                }
               
            }
            rstBuffer.append(level);
        }
        
        //System.out.println(rstBuffer.toString());
        for (int i = rstBuffer.length() - 1; i >= 0; i--) {
            //System.out.println(i + " " + rstBuffer.charAt(i));
            //System.out.println((rstBuffer.charAt(i) == ','));
            if (rstBuffer.charAt(i) != ',' && rstBuffer.charAt(i) != '#') {
                //System.out.println((rstBuffer.charAt(i) != ','));
                rstBuffer.insert(i + 1, '}');
                return rstBuffer.substring(0, i + 2);
            }
        }
        return rstBuffer.append('}').toString();
    }
    
    /**
     * This method will be invoked second, the argument data is what exactly
     * you serialized at method "serialize", that means the data is not given by
     * system, it's given by your own serialize method. So the format of data is
     * designed by yourself, and deserialize it here as you serialize it in 
     * "serialize" method.
     */
    public TreeNode deserialize(String data) {
        // write your code here
        if (data == null || data.length() == 0 || data.equals("{}")) {
            return null;
        }
        String[] vals = data.substring(1, data.length() - 1).split(",");
        TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
        List<TreeNode> list = new ArrayList<TreeNode>();
        list.add(root);
        for (int i = 1; i < vals.length; i++) {
            if (!vals[i].equals("#")) {
                TreeNode node = new TreeNode(Integer.parseInt(vals[i]));
                int parentIdx = (i - 1) / 2;
                if (i == (2 * parentIdx + 1)) {
                    list.get(parentIdx).left = node;
                }
                if (i == (2 * parentIdx + 2)) {
                    list.get(parentIdx).right = node;
                }
                list.add(node);
            }
        }
        return root;
    }
}

 

posted on 2017-06-13 08:42  codingEskimo  阅读(136)  评论(0编辑  收藏  举报

导航