Post

105. Construct Binary Tree from Preorder and Inorder Traversal

url:https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/

Example


input
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

💻 Code

Approach :

1
2
3
4
5
6
          root
preorder = [3,  9,  20,  15,  7]

inorder  = [9,  3,  15,  20,  7]
            |       |_________|
           left        right
  • preorder: increasing by 1, which is the current parent
  • inorder: current index splits for left & right subtrees

1. Brute Force


  • TC : $O(n^2)$
    • Recursion: $O(n)$
    • list.index(int) : $O(n)$
  • SC: $O(n)$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        # base case
        if not preorder or not inorder:
            return None

        # set the current first node of preorder as a root
        root_val = preorder[0]
        root = TreeNode(root_val)

        # recognize where we split in left & right
        mid = inorder.index(root_val)
        
        # in preorder, the first index will always be a root
        # the current index in inorder will be increased if there are more left node
        # thus, left: [1:mid + 1], right: [mid + 1:]
        # split except the current parent node (inorder)
        root.left = self.buildTree(preorder[1:mid + 1], inorder[:mid])
        root.right = self.buildTree(preorder[mid + 1:], inorder[mid + 1:])

        return root

The above recursion method identifies the next parent node and connects with its children. The gist of it is figuring out how the components of preorder and inorder represent when it is converted to a tree.

The inefficiency of this method is accessing the current parent point of the inorder since it uses index() function. This searches index traversing an array from index 0, which means $O(n)$. Since this is a recursion the time complexity will be $O(n^2)$.

Since we create a new tree with arrays, the Space Complexity has to be $O(n)$.

2. Optimised Solution


✅ Hash map

  • TC : $O(n)$
    • Recursion: $O(n)$
    • hash map : $O(1)$
  • SC: $O(n)$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        # {9: 0, 3: 1, 15: 2, 20: 3, 7: 4}
        # this takes O(n), but outside of the recursion.
        inorder_map = {val: idx for idx, val in enumerate(inorder)}
        
        # set a global reference so that we can access the current parent node.
        pre_idx = [0]

        def build(in_start, in_end):
            if in_start > in_end:
                return None

            root_val = predorder[pre_idx[0]]
            pre_idx[0] += 1
            root = TreeNode(root_val)
            
            # Using map, O(1)!!
            mid = inorder_map[root_val]

            root.left = build(in_start, mid - 1)
            root.right = build(mid + 1, in_end)

            return root
        
        return build(0, len(inorder) - 1)



This post is licensed under CC BY 4.0 by the author.