天天看點

#yyds幹貨盤點# LeetCode 熱題 HOT 100:從前序與中序周遊序列構造二叉樹

題目:

給定兩個整數數組 preorder 和 inorder ,其中 preorder 是二叉樹的先序周遊, inorder 是同一棵樹的中序周遊,請構造二叉樹并傳回其根節點。

示例 1:

輸入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

輸出: [3,9,20,null,null,15,7]

示例 2:

輸入: preorder = [-1], inorder = [-1]

輸出: [-1]

class Solution {
    private Map<Integer, Integer> indexMap;

    public TreeNode myBuildTree(int[] preorder, int[] inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) {
        if (preorder_left > preorder_right) {
            return null;
        }

        // 前序周遊中的第一個節點就是根節點
        int preorder_root = preorder_left;
        // 在中序周遊中定位根節點
        int inorder_root = indexMap.get(preorder[preorder_root]);
        
        // 先把根節點建立出來
        TreeNode root = new TreeNode(preorder[preorder_root]);
        // 得到左子樹中的節點數目
        int size_left_subtree = inorder_root - inorder_left;
        // 遞歸地構造左子樹,并連接配接到根節點
        // 先序周遊中「從 左邊界+1 開始的 size_left_subtree」個元素就對應了中序周遊中「從 左邊界 開始到 根節點定位-1」的元素
        root.left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
        // 遞歸地構造右子樹,并連接配接到根節點
        // 先序周遊中「從 左邊界+1+左子樹節點數目 開始到 右邊界」的元素就對應了中序周遊中「從 根節點定位+1 到 右邊界」的元素
        root.right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
        return root;
    }

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int n = preorder.length;
        // 構造哈希映射,幫助我們快速定位根節點
        indexMap = new HashMap<Integer, Integer>();
        for (int i = 0; i < n; i++) {
            indexMap.put(inorder[i], i);
        }
        return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
    }
}