Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

https://leetcode.com/problems/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.

解题思路:

这题是二叉树遍历中比较难的题目,但是也比较常见,考的是对pre、in或者post遍历的更深的理解。

http://articles.leetcode.com/2011/04/construct-binary-tree-from-inorder-and-preorder-postorder-traversal.html

主要是参考上面这个文章的思路。

对于下面的二叉树:

                       7

                    /    \

                10        2

              /     \      /

           4        3     8

                     \     /

                     1    11

preorder的遍历结果:7  10  4  3  1  2  8  11

inorder的便利结果:  4  10  3  1  7  11 8  2

要解决这道题目,就要分别利用preorder和inorder遍历的两个性质。preoder的第一个元素确定为根节点,然后再在inorder里,它左侧的就是左子树的全部节点,右侧的就是右子树的全部节点。然后再对左子树这些节点,递归调用上面的方法。

比如,上面的例子,7为preorder的第一个元素,所以是整个树的根。那么在inorder中,7往左的4-1是左子树,往右的11-2是右子树。我们回到preorder中,10为左子树的根,2为右子树的根。再去preorder里面,10左侧的4为左子树,右侧的3、1为右子树。2往左的11和8为左子树。再递归,直至结束。

所以这里递归的,其实是preorder和inorder这两个数组的左右边界。取root,永远是preorder边界内的第一个元素。然后用root在inorder里的index,去更新下一递归inorder的范围。

preorder的范围如何确定?从root往后算长度,左子树长度的就是左子树范围,右子树长度的,就是右子树范围。

代码如下:

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return helper(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1);
    }
    
    public TreeNode helper(int[] preorder, int[] inorder, int preStart, int preEnd, int inStart, int inEnd) {
        if(preStart > preEnd || inStart > inEnd) {
            return null;
        }
        TreeNode node = new TreeNode(preorder[preStart]);
        int index = 0;
        for(int i = inStart; i <= inEnd; i++){
            if(inorder[i] == preorder[preStart]) {
                index = i;
                break;
            }
        }
        node.left = helper(preorder, inorder, preStart + 1, preStart + index - inStart, inStart, index - 1);
        node.right = helper(preorder, inorder, preStart + index - inStart + 1, preEnd, index + 1, inEnd);
        return node;
    }
}

 

posted on 2015-04-25 22:00  NickyYe  阅读(994)  评论(0编辑  收藏  举报