LeetCode 297. Serialize and Deserialize Binary Tree 二叉樹序列化反序列化

胡椒五菇發表於2019-01-19

LeetCode 297. Serialize and Deserialize Binary Tree

題目大意: 將二叉樹序列化,返回序列化的String,和反序列化還原。

解題思路:
技巧在於將null記錄為#便於將來判斷。有兩種解法。

  1. Level Order Traversal – BFS的思想將每一層記錄下來,反序列化時也按照層級遍歷的方法依次設定為上一個queue裡面的元素的左孩子和右孩子。
  2. 更好的方法為preorder traversal,是可以handle變種題目的解法,利用preorder是root—>left->right的順序,用一個deque來不斷把頭部的元素poll出,遞迴呼叫函式構建還原二叉樹。
    //Solution 1: using Level order traversal
    public static String serialize(TreeNode root) {
        if (root == null ) {
            return "";
        }

        StringBuilder sb = new StringBuilder();
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        q.offer(root);
        while(!q.isEmpty()) {
            TreeNode curr = q.poll();
            if (curr == null) {
                sb.append("#,");
            } else {
                sb.append(curr.val + ",");
                q.offer(curr.left);
                q.offer(curr.right);
            }
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    /**
     *      1
     *     / 
     *    2   3
     *   /   / 
     *  4   2   4
     *  /
     * 4
     * [1,2,3,4,#,2,4,4]
     * @param input
     * @return
     */

    public static TreeNode deSerialize(String input) {
        if (input == null || input.length() == 0) {
            return null;
        }
        String[] strs = input.split(",");
        TreeNode root = new TreeNode(Integer.valueOf(strs[0]));
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        q.offer(root);

        for(int i = 1; i < strs.length; i++){
            TreeNode curr = q.poll();
            if (curr == null) continue;
            if (!strs[i].equals("#")) {
                curr.left = new TreeNode(Integer.valueOf(strs[i]));
                q.offer(curr.left);
            }

            i++;

            if (i < strs.length && !strs[i].equals("#")) {
                curr.right = new TreeNode(Integer.valueOf(strs[i]));
                q.offer(curr.right);
            }

        }
        return root;

    }
    //Solution II: using 2 preorder traversal
    private static final String DELIMITER = ",";
    private static final String NN = "#";

    // Encodes a tree to a single string.
    public static String serialize2(TreeNode root) {
        //using preorder traversal
        StringBuilder res = new StringBuilder();
        serializeHelper(root, res);
        res.deleteCharAt(res.length() - 1);
        return res.toString();
    }
    private static void serializeHelper(TreeNode root, StringBuilder res) {
        if (root == null) {
            res.append(NN).append(DELIMITER);
            return;
        }
        res.append(root.val).append(DELIMITER);
        serializeHelper(root.left, res);
        serializeHelper(root.right, res);
    }

    // Decodes your encoded data to tree.
    public static TreeNode deserialize2(String data) {
        Deque<String> deque = new LinkedList<>();
        deque.addAll(Arrays.asList(data.split(DELIMITER)));
        return deserializeHelper(deque);
    }
    private static TreeNode deserializeHelper(Deque<String> deque) {
        String now = deque.pollFirst();
        if (now.equals(NN)) {
            return null;
        }
        TreeNode node = new TreeNode(Integer.parseInt(now));
        node.left = deserializeHelper(deque);
        node.right = deserializeHelper(deque);
        return node;
    }
    public static void main(String[] args) {
        //solution 1 level order
        TreeNode root1 = deSerialize("1,2,3,4,#,5,6,7");
        String result1 = serialize(root1);
        System.out.println(result1);

        //solution 2 preorder - 變種,可以要求輸出一個LinkedList,而不是String
        TreeNode root2 = deserialize2("3,4,1,#,#,2,#,#,5,#,6,#,#");
        String result2 = serialize2(root2);

        System.out.println(result2);

    }

相關文章