LeetCode 106 从中序与后序遍历序列构造二叉树

LeetCode 106 从中序与后序遍历序列构造二叉树

问题描述:
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。

执行用时:3 ms, 在所有 Java 提交中击败了72.97%的用户
内存消耗:39.3 MB, 在所有 Java 提交中击败了42.05%的用户

class Solution {
    //保存inorder中元素、位置的映射
    private HashMap<Integer, Integer> inorderMap = new HashMap<>();

    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(inorder==null || postorder==null || inorder.length==0 || postorder.length==0) {
            return null;
        }

        //构建inorder的hashMap
        for(int i=0; i<inorder.length; i++) {
            inorderMap.put(inorder[i], i);
        }

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

    //range1表示在inorder中的范围
    //range2表示在postorder中的范围
    public TreeNode buildTree(int[] inorder, int[] postorder, int[] range1, int[] range2) {
        if(range1[0]>range1[1] || range2[0]>range2[1]) {
            return null;
        }

        //找到当前根节点在inorder中的位置,使用hashMap优化查找速度由O(N)到O(1)
        int rootVal = postorder[range2[1]];
        int rootIdx = 0;
        rootIdx = inorderMap.get(rootVal);

        //由当前根节点切分inorder数组
        int leftTreeSize = rootIdx - range1[0];
        int rightTreeSize = range1[1] - rootIdx;

        //建立当前根节点对象
        TreeNode root = new TreeNode(rootVal);
        //建立左、右子树
        TreeNode leftRoot = buildTree(inorder, postorder, 
            new int[]{range1[0], rootIdx-1}, 
            new int[]{range2[0], range2[0]-1+leftTreeSize}
        );
        TreeNode rightRoot = buildTree(inorder, postorder, 
            new int[]{rootIdx+1, range1[1]},
            new int[]{range2[1]-rightTreeSize, range2[1]-1}
        );
        root.left = leftRoot;
        root.right = rightRoot;

        return root;
    }
}
posted @ 2020-10-09 13:30  CodeSPA  阅读(88)  评论(0编辑  收藏  举报