LeetCode之通过二叉树的中序遍历和后序遍历还原二叉树

问题描述:

/**
 * Given inorder and postorder traversal of a tree, construct the binary tree.
 *
 * Note:
 * 
 * You may assume that duplicates do not exist in the tree.
 * 
 */

根据给出的二叉树的中序遍历和后序遍历的结果,来还原这棵二叉树,假定这个二叉树没有重复的孩子。
思路:先通过后序遍历的结果求出二叉树的根节点,然后通过递归的方式依次来求左子树和右子树。代码如下:

public static TreeNode buildTree(int[] inorder, int[] postorder) {
        return buildTree(inorder, 0, inorder.length - 1, postorder, 0,
                postorder.length - 1);
    }

    public static TreeNode buildTree(int[] inorder, int is, int ie, int[] postorder,
            int ps, int pe) {
        if (is > ie || ps > pe)
            return null;
        int rootVal = postorder[pe];
        TreeNode root = new TreeNode(rootVal);
        for (int i = is; i <= ie; i++) {
            if (inorder[i] == rootVal) {
                TreeNode left = buildTree(inorder, is, i - 1, postorder, ps, ps+ i - is - 1);
                TreeNode right = buildTree(inorder, i + 1, ie, postorder, pe- ie + i, pe - 1);
                root.left = left;
                root.right = right;
            }
        }
        return root;
    }
    //测试代码
            public static void main(String args[])
            {
                int[]inorder = new int[]{4,2,5,1,6,3};
                int[]postorder = new int[]{4,5,2,6,3,1};
                buildTree(inorder,postorder);
            }

很显然后序遍历的结果的最后一位就是root节点。然后求左子树:

TreeNode left = buildTree(inorder, is, i - 1, postorder, ps, ps+ i - is - 1);

这段代码是通过递归的方式来找左子树,首先它通过if (inorder[i] == rootVal)来找到中序结果的root节点所在,在递归时,把中序遍历的结果分为两部分,root节点前面的必然是左子树,root节点后面的必然是右子树,所以左子树在中序结果中的范围就是[is,i-1],左子树在后序结果中的范围就是[ps,ps+i-is-1]:

          i 0,1,2,3,4,5
中序遍历序列:4,2,5,1,6,3
后序遍历序列:4,5,2,6,3,1
现在在中序遍历的序列中找到了root节点的位置i,那么就可以知道左子树在中序结果中的范围为[is,i-1](is为中序的起始位置).
左子树在后序结果中的范围为[ps,ps+i-is-1](ps为后序的起始位置,因为左子树的长度为i-1-is,所以在后序结果中截止范围为ps+(i-1-is)).
右子树在中序结果中的范围为[i+1,ie](ie为中序的结束位置),右子树在后序结果中的范围为[pe- ie + i,pe - 1].

你可能感兴趣的:(LeetCode)