1. 程式人生 > 實用技巧 >二叉樹--用前序和中序遍歷序列構造二叉樹(leetcode 105

二叉樹--用前序和中序遍歷序列構造二叉樹(leetcode 105

題解

你可以假設樹中沒有重複的元素。這句話代表什麼呢?

這樣可以保證結點的數值可以在中序遍歷陣列中唯一確定,這樣還原出的二叉樹是唯一確定的

思路

  1. 先序陣列中最左邊的值就是樹的根節點的值,記為h,並用h生成頭節點,記為head。然後在中序陣列找到h,設位置為i。在中序陣列中,i左邊的陣列就是頭節點左子樹的中序陣列,假設長度為l,則左子樹的先序陣列就是先序陣列中h往右長度為l的陣列。

  2. 用左子樹的先序和中序陣列,遞迴構建左子樹,返回的頭節點為left

  3. i右邊的陣列就是頭節點右子樹的中序陣列,假設長度為r。先序陣列中右側等長的部分就是頭節點右子樹的先序陣列

  4. 用右子樹的先序和中序陣列,遞迴構建右子樹,返回的右節點記為right

  5. 將head的左子,右子設為left,right,返回head,過程結束。

在中序陣列中找到位置i可以用雜湊表實現。

時間複雜度:O(n)
空間複雜度:O(n)

程式碼

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int preLen = preorder.length;
        int inLen = inorder.length;
        if (preLen != inLen){
            throw new RuntimeException("Error");
        }

        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < inLen; i++){
            map.put(inorder[i], i);
        }

        return helper(preorder, 0, preLen - 1, inorder, 0, inLen - 1, map);
    }

    public TreeNode helper(int[] preorder, int preLeft, int preRight,
                           int[] inorder, int inLeft, int inRight,
                           Map<Integer, Integer> map){
        if (preLeft > preRight || inLeft > inRight){
            return null;
        }
        int rootVal = preorder[preLeft];
        TreeNode root = new TreeNode(rootVal);
        int index = map.get(rootVal);

        root.left = helper(preorder, preLeft + 1, index - inLeft + preLeft,
                            inorder, inLeft, index - 1, map);
        root.right = helper(preorder, index - inLeft + preLeft + 1, preRight,
                            inorder, index + 1, inRight, map);
        return root;
    }