zoukankan      html  css  js  c++  java
  • 105. Construct Binary Tree from Preorder and Inorder Traversal

    题目:

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

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

    链接: http://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

    题解:

    根据前序遍历和中序遍历重建二叉树,方法是自顶向下recursive来构建。前序就是 root -> left -> right,中序是 left -> root -> right。所以每次preorder[preLo]就是root。接下来preorder[preLo + 1]就是当前root的left child, 接下来在inorder中找到root的index  - rootAtInorder,则 inorder[rootAtInOrder + 1]就是当前root的right child。最后做递归的时候要注意,求left child时,inHi = rootAtInOrder - 1,求right child时, inLo = rootAtInOrder + 1。  应该还有不少更简便的方法,要好好想一想。

    Time Complexity - O(n), Space Complexity - O(n)。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder == null || inorder == null || preorder.length != inorder.length || preorder.length == 0)
                return null;
            return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);    
        }
        
        private TreeNode buildTree(int[] preorder, int preLo, int preHi, int[] inorder, int inLo, int inHi) {
            if(preLo > preHi || inLo > inHi)
                return null;
            TreeNode root = new TreeNode(preorder[preLo]);
            
            int rootAtInorder = 0;
            for(int i = inLo; i <= inHi; i++) {
                if(inorder[i] == root.val) {            //because no duplicate
                    rootAtInorder = i;
                    break;
                }                  
            }
            
            int leftSubTreeLen = rootAtInorder - inLo;
            root.left = buildTree(preorder, preLo + 1, preLo + leftSubTreeLen, inorder, inLo, rootAtInorder - 1);
            root.right = buildTree(preorder, preLo + leftSubTreeLen + 1, preHi, inorder, rootAtInorder + 1, inHi);
            return root;
        }
    }

    Discussion里还有一些很好的写法, 比如使用一个stack进行iterative重建;或者不做辅助函数,使用arrays.copyof,把原array分割后分别递归计算left child和right child。

    要多思考多练习。

    PS: 今天 Twitter裁员 8%, 好吓人。

    二刷:

    方法和一刷一样,就是使用递归来重建树。找到根节点以后,求出左子树长度和右子树长度,然后分别递归调用辅助方法求出左child和右child,最后返回root就可以了。各种边界要想得细一点。

    可以使用HashMap保存inorder的key, value,这样在递归调用辅助方法时可以O(1)拿到rootVal,就不用顺序搜索了。 (下一道题也是一样)

    Java:

    Time Complexity - O(n), Space Complexity - O(n)。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if (preorder == null || inorder == null || preorder.length != inorder.length || preorder.length == 0) return null;
            return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
        }
        
        private TreeNode buildTree(int[] preorder, int preLo, int preHi, int[] inorder, int inLo, int inHi) {
            if (preLo > preHi || inLo > inHi) return null;
            int rootVal = preorder[preLo];
            TreeNode root = new TreeNode(rootVal);
            int rootIndexAtInorder = inLo;
            while (rootIndexAtInorder <= inHi) {
                if (inorder[rootIndexAtInorder] == rootVal) break;
                rootIndexAtInorder++;
            }
            int leftTreeLen = rootIndexAtInorder - inLo;
            root.left = buildTree(preorder, preLo + 1, preLo + leftTreeLen, inorder, inLo, rootIndexAtInorder - 1);
            root.right = buildTree(preorder, preLo + leftTreeLen + 1, preHi, inorder, rootIndexAtInorder + 1, inHi);
            return root;
        }
    }

    Reference:

    https://leetcode.com/discuss/63586/neat-java-solution-pretty-easy-to-read

    https://leetcode.com/discuss/2297/the-iterative-solution-is-easier-than-you-think

    https://leetcode.com/discuss/28271/my-o-n-19ms-solution-without-recusion-hope-help-you

    https://leetcode.com/discuss/18101/sharing-my-straightforward-recursive-solution

    https://leetcode.com/discuss/12179/my-accepted-java-solution

    https://leetcode.com/discuss/32414/recursive-solution-in-java

  • 相关阅读:
    iaas,paas,saas理解
    July 06th. 2018, Week 27th. Friday
    July 05th. 2018, Week 27th. Thursday
    July 04th. 2018, Week 27th. Wednesday
    July 03rd. 2018, Week 27th. Tuesday
    July 02nd. 2018, Week 27th. Monday
    July 01st. 2018, Week 27th. Sunday
    June 30th. 2018, Week 26th. Saturday
    June 29th. 2018, Week 26th. Friday
    June 28th. 2018, Week 26th. Thursday
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4437296.html
Copyright © 2011-2022 走看看