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 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 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;
        }
    }

你可能感兴趣的:(ACMer之路,________搜索,数据结构,________水题)