Given two integer arrays preorder
and inorder
where preorder
is the preorder traversal of a binary tree and inorder
is the inorder traversal of the same tree, construct and return the binary tree.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
What are the characteristics of the input arrays?
Both preorder
and inorder
arrays will contain unique values (since they represent a valid binary tree). They will have no duplicates and will be of the same length.
How large can the input arrays be?
For the sake of this problem, you may assume the input arrays can have a length up to 2000
.
Preorder
traversal visits nodes in the order: root -> left -> right.Inorder
traversal visits nodes in the order: left -> root -> right.preorder
list is the root of the tree.inorder
list; elements to the left of this root in inorder
are in the left subtree, and elements to the right are in the right subtree.preorder
and inorder
lists.Here’s the Python implementation:
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def buildTree(preorder, inorder):
if not preorder or not inorder:
return None
# The first element of preorder is the root of the tree
root_val = preorder[0]
root = TreeNode(root_val)
# Find the index of the root in the inorder array
root_index_inorder = inorder.index(root_val)
# All elements to the left of root_index_inorder in inorder are in the left subtree
left_inorder = inorder[:root_index_inorder]
# All elements to the right of root_index_inorder in inorder are in the right subtree
right_inorder = inorder[root_index_inorder + 1:]
# Divide the preorder list into parts for left and right subtrees
left_preorder = preorder[1:1 + len(left_inorder)]
right_preorder = preorder[1 + len(left_inorder):]
# Recursively construct the left and right subtrees
root.left = buildTree(left_preorder, left_inorder)
root.right = buildTree(right_preorder, right_inorder)
return root
Finding the root index in the Inorder list: This takes O(n) where n
is the number of elements. However, this can be optimized by using a hashmap (dictionary) to store the indices of each value in the inorder list. This reduces the lookup time to O(1).
Constructing the tree: For each node, we perform constant time operations plus recursive calls. Each element in the preorder and inorder lists is processed once, leading to a time complexity of O(n).
By optimizing the index lookup with a hashmap, the overall complexity can be improved:
```python def buildTree(preorder, inorder): inorder_index_map = {value: index for index, value in enumerate(inorder)}
def helper(pre_left, pre_right, in_left, in_right):
if pre_left > pre_right:
return None
# The first element in the current preorder segment is the root
root_val = preorder[pre_left]
root = TreeNode(root_val)
# Index of the root in the inorder array
root_index_inorder = inorder_index_map[root_val]
# Size of the left subtree
left_subtree_size = root_index_inorder - in_left
# Recursively build the left and right subtree
root.left = helper(pre_left + 1, pre_left + left_subtree_size, in_left, root_index_inorder - 1)
root.right = helper(pre_left + 1 + left_subtree_size, pre_right, root_index_inorder + 1, in_right)
return root
return helper(0, len(preorder) - 1, 0, len(inorder) - 1)
Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?