Construct Binary Tree from Preorder and Inorder Traversal

Given preorder and inorder traversal of a tree, construct the binary tree.

Divide and Conquer

Time Complexity
O(nlogn)
For every level, it takes O(1) to find the root of preorder and O(n) to find the inRoot position, there are logn level, so the time complexity is O(nlogn)

You are here!
Your runtime beats 46.38 % of java submissions.
Space Complexity
O(1)

思路

First, we need to be very familiar with preorder and inorder of a binary tree.

Preorder sequence:50,30,10,40,70,60,90
Inorder sequence: 10,30,40,50,60,70,90

In a preorder sequence, leftmost element is the root of the tree.
So 50 is root for given sequences.
By searching '50' in inorder sequence, we can find all elements on left side of '50' are in left subtree and elements on right are in right subtree.

Draw it.

Preorder sequence:50,30,10,40,70,60,90
Inorder sequence: 10,30,40,50,60,70,90
So for preorder, we know 30,10,40 is left subtree; 70,60,90 is right subtree
for inorder, 10,30,40 is left subtree; 60,70,90 is right subtree

Now we see the left subtree part
Preorder sequence: 30, 10, 40
Inorder sequence: 10, 30, 40
So 30 is the root
Since left and right sub tree has only 1 element so we will simply add them to the root node 30.

Now we see the right subtree part
Preorder sequence: 70,60,90
inorder sequence: 60,70,90
Since left and right sub tree has only 1 element so we will simply add them to the root node 70.

We don't use preRight here because we don't need it when we do recursion.

代码

public TreeNode buildTree(int[] preorder, int[] inorder) {
    //corner case
    if(preorder == null || preorder.length == 0 || inorder == null || inorder.length == 0) return null;
    return buildTree(preorder, 0, inorder, 0, inorder.length - 1);
}

private TreeNode buildTree(int[] preorder, int leftPre, int[] inorder, int leftIn, int rightIn){
    //base case
    if(leftIn > rightIn) return null;
    
    TreeNode root = new TreeNode(preorder[leftPre]);
    if(leftIn == rightIn) return root;
    int inRoot = 0;
    for(int i = leftIn; i <= rightIn; i++){
        if(inorder[i] == preorder[leftPre]){
            inRoot = i;
        }
    }
    root.left = buildTree(preorder, leftPre + 1, inorder, leftIn, inRoot - 1);
    root.right = buildTree(preorder, leftPre + inRoot - leftIn + 1, inorder, inRoot + 1, rightIn);
    return root;
}

优化

Time Complexity
O(n)
You are here!
Your runtime beats 75.67 % of java submissions.
Space Complexity
O(n)

思路

The method is the same as above but we can improve time complexity by increase space complexity. In last method, we use O(n) to find the position of the root node in inorder sequence. We can use a global hashmap (key is the number in inorder sequence, value is the index of the number). Then we can use O(1) to find the root position in inorder sequence.

代码

private Map<Integer, Integer> inMap = new HashMap<Integer, Integer>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
    //corner case
    if(preorder == null || preorder.length == 0 || inorder == null || inorder.length == 0) return null;
    for(int i = 0; i < inorder.length; i++){
        inMap.put(inorder[i], i);
    }
    return buildTree(preorder, 0, inorder, 0, inorder.length - 1, inMap);
}

private TreeNode buildTree(int[] preorder, int leftPre, int[] inorder, int leftIn, int rightIn, Map<Integer, Integer> map){
    //base case
    if(leftIn > rightIn) return null;
    
    TreeNode root = new TreeNode(preorder[leftPre]);
    if(leftIn == rightIn) return root;
    int inRoot = map.get(preorder[leftPre]);
    // for(int i = leftIn; i <= rightIn; i++){
    //     if(inorder[i] == preorder[leftPre]){
    //         inRoot = i;
    //     }
    // }
    root.left = buildTree(preorder, leftPre + 1, inorder, leftIn, inRoot - 1, inMap);
    root.right = buildTree(preorder, leftPre + inRoot - leftIn + 1, inorder, inRoot + 1, rightIn, inMap);
    return root;
}

annielulu
5 声望5 粉丝