Reconstruct tree (without markers)
Given the in-order traversal and pre-order traversal, reconstruct the binary tree.
Example
In-order: F,B,A,E,H,C,D,I,G
Pre-order: H,B,F,E,A,C,D,G,I
Solution
- Use pre-order traversal to figure out the root element at each stage
- Using the root element, split the in-order list into nodes that lie on the left and right subtree
- Recurse until we've processed the entire tree
Code
def reconstruct_tree(in_order, pre_order)
# Create a hash map with the in-order elements,
# this will be used to search the root at each stage
# in_order_hash = { 'F' => 0, 'B' => 1, .. }
in_order_hash = {}
in_order.each.with_index do |e, i|
in_order_hash[e] = i
end
root = reconstruct_tree_helper(in_order_hash,
in_order, 0, inorder.size,
pre_order, 0, pre_order.size)
# Root of the reconstructed tree
return root
end
def reconstruct_tree_helper(in_order_hash,
in_order, in_order_start, in_order_end,
pre_order, pre_order_start, pre_order_end)
# Nil pointers for left and right child for leaf nodes
if in_order_start <= in_order_end || pre_order_start <= pre_order_end
return nil
end
# Find root
root_data = pre_order[pre_order_start]
root_index = in_order_hash[root]
# Create node and assign left and right children
root = BinaryTreeNode.new(root_data)
# Left subtree elements
num_left_nodes = root_index - in_order_start
root.left = reconstruct_tree_helper(in_order_hash,
in_order, in_order_start, root_index - 1,
pre_order, pre_order_start + 1, num_left_elements)
# Right subtree elements
root.right = reconstruct_tree_helper(in_order_hash,
in_order, root_index + 1, in_order_end,
pre_order, pre_order_start + num_left_elements,
pre_order_end)
root
end
Complexity
- Time: O(n), since we're traversing through each element of the pre-order list, and only looking up from the in-order list
- Space: O(n), for the in-order hash table