leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal

生命不息,奮鬥不止


@author stormma
@date 2018/03/23

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

For example, given

preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
Return the following binary tree:

    3
   / \
  9  20
    /  \
   15   7

即根據中序和前序遍歷來重新構造二叉樹的問題。

步驟如下:
1. 根據前序遍歷即可知道root節點,
2. 之後在中序遍歷中找到root節點的 index值, 那麼中序遍歷數組中[0-index - 1]就是root的左子樹, 另外一部分便是root的右子樹。
3. 遞歸求解即可

未優化版本: 24ms

    /**
     * running time: 24ms
     */
    static class Solution1 {
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
        }

        /**
         * preorder = [3,9,20,15,7]
         * inorder = [9,3,15,20,7]
         * 我們可以知道root節點是3, 然後再inorder中找3, 那麼inorder中3左邊的必定是root的左子樹, 右邊的必定是它的右子樹, 遞歸解決之
         *
         * @param pre
         * @param preStart
         * @param preEnd
         * @param in
         * @param inStart
         * @param inEnd
         * @return
         */
        private TreeNode buildTree(int[] pre, int preStart, int preEnd, int[] in, int inStart, int inEnd) {
            if (preStart > preEnd || inStart > inEnd) return null;
            TreeNode node = new TreeNode(pre[preStart]);
            for (int i = inStart; i <= inEnd; i++) {
                if (in[i] == pre[preStart]) {
                    //
                    node.left = buildTree(pre, preStart + 1, preStart + i - inStart, in, inStart, i - 1);
                    node.right = buildTree(pre, preStart + i - inStart + 1, preEnd, in, i + 1, inEnd);
                }
            }
            return node;
        }
    }

每次遞歸, 我們都要在inorder數組中去找當前節點的index, 所以可以考慮用map來緩存一下這個值。

優化版本: 7ms

    /**
     * 優化
     * running time 7ms
     */
    static class Solution2 {
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if (inorder == null || inorder.length == 0 || preorder == null || preorder.length == 0) return null;
            Map<Integer, Integer> map = new HashMap<>();
            for (int i = 0; i < inorder.length; i++) {
                map.put(inorder[i], i);
            }
            return buildTree(map, preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
        }

        /**
         * preorder = [3,9,20,15,7]
         * inorder = [9,3,15,20,7]
         * 我們可以知道root節點是3, 然後再inorder中找3, 那麼inorder中3左邊的必定是root的左子樹, 右邊的必定是它的右子樹, 遞歸解決之
         *
         * @param pre
         * @param preStart
         * @param preEnd
         * @param in
         * @param inStart
         * @param inEnd
         * @return
         */
        private TreeNode buildTree(Map<Integer, Integer> map, int[] pre, int preStart, int preEnd
                , int[] in, int inStart, int inEnd) {
            if (preStart > preEnd || inStart > inEnd) return null;
            TreeNode node = new TreeNode(pre[preStart]);
            int i = map.get(pre[preStart]);
            node.left = buildTree(map, pre, preStart + 1, preStart + i - inStart
                            , in, inStart, i - 1);
            node.right = buildTree(map, pre, preStart + i - inStart + 1, preEnd
                            , in, i + 1, inEnd);
            return node;
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章