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

posted @ 2015-04-18 13:41  YRB  阅读(607)  评论(0编辑  收藏  举报