Solution: Build Binary Tree from Preorder and Inorder Traversal

Let's solve the Build Binary Tree from Preorder and Inorder Traversal problem using the Tree Depth-First Search pattern.

Statement#

Create a binary tree from two integer arrays, p_order and i_order, where p_order represents a preorder traversal of a binary tree, and i_order represents an inorder traversal of the same tree.

Constraints:

  • 11 \leq p_order.length, i_order.length 1000\leq1000
  • i_order.length ==== p_order.length
  • 1000-1000 \leq p_order[i], i_order[i] 1000\leq 1000
  • p_order and i_order consist of unique values.
  • Each value of i_order also appears in p_order and vice versa.

Solution#

To construct the binary tree from the given preorder and inorder traversals, we can use the preorder traversal to decide the root node of each subtree and inorder traversal to determine the left and right subtrees of that node.

In a preorder traversal, the root node of a tree is always visited before any of its children. Therefore, the first node in the preorder list is the root node of the entire tree. In an inorder traversal, the order of traversal is left, root, and then right. Therefore, the middle element will be the root, the element before the middle will be the left child, and the element after the middle will be the right child. So, we can use the inorder list to determine the left and right subtrees of this root node. We will search the node value in the inorder list, the elements before this value will create the left subtree of this node, and the elements after this value will create the right subtree of this node. We will recursively perform these steps to build the whole tree.

Let’s create a recursive function that will perform the following steps:

  1. Select the first element from the preorder list. Increment the preorder index, p_index, to prepare for the next recursive call.

  2. Make a new tree node using the selected element as its data.

  3. Find the index of the selected element in the inorder list, i_order. The elements before this in_index will be part of the left subtree of this node, and the elements after this in_index will be part of the right subtree of this node.

  4. Make the following recursive call to add the elements from left to in_index-1 from the inorder list into the left subtree of the node.

root.left = build_tree_helper(p_order, i_order, left, in_index-1, mapping, p_index)
  1. Make the following recursive call to add the elements from in_index+1 to right from the inorder list into the right subtree of the node.
root.right = build_tree_helper(p_order, i_order, in_index+1, right, mapping, p_index)
  1. If left > right, it means there are no further elements in the list, and it will return NULL.

The following illustration depicts the steps above:

Created with Fabric.js 3.6.6 root 1 2 4 8 9 5 3 6 7 8 4 9 2 5 1 6 3 7 1 Preorder Inorder Select the first element from the preorder list, and create the root node with thisvalue. Find this value in the inorder list. The elements before this value in theinorder list will be part of the left subtree, and the elements after this value willbe part of the right subtree.

1 of 9

Created with Fabric.js 3.6.6 1 2 1 2 4 8 9 5 3 6 7 8 4 9 2 5 1 6 3 7 root Preorder Inorder Select the second element from the preorder list, and create the left child of the rootnode with this value. Find this value in the inorder list. The elements before thisvalue in the inorder list will be part of the left subtree, and the elements after thisvalue will be part of the right subtree.

2 of 9

Created with Fabric.js 3.6.6 1 2 4 1 2 4 8 9 5 3 6 7 8 4 9 2 5 1 6 3 7 root Preorder Inorder Select the third element from the preorder list, and add it to the tree.Find this value in the inorder list. The elements before this value in the inorder listwill be part of the left subtree, and the elements after this value will be part of theright subtree.

3 of 9

Created with Fabric.js 3.6.6 1 2 4 8 1 2 4 8 9 5 3 6 7 8 4 9 2 5 1 6 3 7 root Preorder Inorder Select the next element from the preorder list, and add it to the tree.

4 of 9

Created with Fabric.js 3.6.6 1 2 4 8 9 1 2 4 8 9 5 3 6 7 8 4 9 2 5 1 6 3 7 root Preorder Inorder Select the next element from the preorder list, and add it to the tree.

5 of 9

Created with Fabric.js 3.6.6 1 2 4 5 8 9 1 2 4 8 9 5 3 6 7 8 4 9 2 5 1 6 3 7 root Preorder Inorder Select the next element from the preorder list, and add it to the tree.

6 of 9

Created with Fabric.js 3.6.6 1 2 3 4 5 8 9 1 2 4 8 9 5 3 6 7 8 4 9 2 5 1 6 3 7 root Preorder Inorder Select the next element from the preorder list, and create the right child of the rootnode with this value. Find this value in the inorder list. The elements before thisvalue in the inorder list will be part of the left subtree, and the elements after thisvalue will be part of the right subtree.

7 of 9

Created with Fabric.js 3.6.6 1 2 3 4 5 6 8 9 1 2 4 8 9 5 3 6 7 8 4 9 2 5 1 6 3 7 root Preorder Inorder Select the next element from the preorder list, and add it to the tree.

8 of 9

Created with Fabric.js 3.6.6 1 2 3 4 5 6 7 8 9 1 2 4 8 9 5 3 6 7 8 4 9 2 5 1 6 3 7 root Preorder Inorder Select the next element from the preorder list, and add it to the tree.

9 of 9

Let’s look at the code for this solution below:

main.py
TreeNode.py
Build Binary Tree from Preorder and Inorder Traversal

Time complexity#

The time complexity of this solution is O(n)O(n), where nn is the number of elements in the preorder or inorder array.

Space complexity#

The space complexity of this solution is O(n)O(n), where nn is the number of elements stored in the map.

Note: Using the hash map to store the inorder list will reduce the time complexity of the search to O(1)O(1). It would otherwise take O(n)O(n) in the case of a list.

Build Binary Tree from Preorder and Inorder Traversal

Lowest Common Ancestor of a Binary Search Tree