1. 程式人生 > 實用技巧 >LeetCode 106 從中序與後序遍歷序列構造二叉樹

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;
    }
}