Build a Tree from Preorder and Inorder Traversals
Reported by candidates from Bloomberg's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The edge case that breaks a naive solution on this Bloomberg OA, reported June 2020, is a skewed tree with 10000 nodes. Your recursive build works on the sample, then blows the stack or crawls because you scanned the inorder array for every root. The task is classic tree reconstruction from preorder and inorder, plus a formatting twist: output level order with # for missing children and trailing # trimmed. If you blank on the details during the live assessment, StealthCoder is the invisible safety net that reads the problem and hands you a working build.
The problem
Reconstruct the unique binary tree described by the preorder and inorder traversals. All values are distinct. Return the constructed tree in level order as strings. Use # for a missing child and remove all trailing # markers. Return an empty array for an empty tree. Function buildTreeLevelOrder(preorder: int[], inorder: int[]) → String[] Examples Example 1 preorder = [3,9,20,15,7] inorder = [9,3,15,20,7] return = ["3","9","20","#","#","15","7"] The root is 3, with leaf 9 and a right subtree rooted at 20. Example 2 preorder = [] inorder = [] return = [] Empty traversals construct an empty tree. Constraints 0 <= preorder.length <= 10000. Both arrays have equal length, contain the same distinct values, and describe a valid tree.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is that preorder gives you the root first, and inorder tells you how many nodes sit in the left subtree. Build a hash map from value to inorder index once, so each root lookup is O(1) and the whole build is O(n). Keep a moving preorder pointer and recurse with inorder bounds: left first, then right. The pitfall is the depth. A fully skewed tree with 10000 nodes means 10000 recursion levels, so consider an iterative approach or know your language's limit. The second pitfall is output. Do a BFS from the root, push # for null children, then pop trailing # entries before returning. Empty input returns an empty array, not ["#"]. StealthCoder is your hedge on the live OA if the index bounds or trimming logic slip under pressure.
The honest play: practice the pattern, and have StealthCoder ready for the one you didn't see coming.
You can drill Build a Tree from Preorder and Inorder Traversals cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play.
Get StealthCoderRelated leaked OAs
This OA pattern shows up on LeetCode as construct binary tree from preorder and inorder traversal. If you have time before the OA, drill that.
You've seen the question.
Make sure you actually pass Bloomberg's OA.
Bloomberg reuses patterns across OAs. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Build a Tree from Preorder and Inorder Traversals FAQ
What's the trick to building a tree from preorder and inorder?+
Preorder's first element is the root. Find that value in inorder, and everything left of it is the left subtree, everything right is the right subtree. Store inorder indexes in a hash map so each lookup is constant time and the whole build stays O(n).
Why does my solution time out on large inputs here?+
You're probably searching inorder linearly for every root, which is O(n^2) on a skewed tree. With up to 10000 nodes that hurts. Precompute a value-to-index map once. Also avoid slicing arrays on each call, since copying adds hidden cost. Pass index bounds instead.
How do I produce the level order output with # markers?+
Run a BFS with a queue starting at the root. For each node, append its value as a string, then enqueue both children, using # when a child is null. After the traversal, pop trailing # entries from the end. Return an empty array if the tree is empty.
What edge cases should I test before submitting?+
Test empty arrays, a single node, a fully left-skewed tree, a fully right-skewed tree, and a case where trailing # markers must be removed. The skewed cases catch recursion depth and bounds mistakes. Example 1 from the problem is a good check for the # placement in the middle.
How do I prepare for this in 48 hours?+
Write the hash map plus recursive build from memory twice, then write the BFS serializer with trailing # trimming. That's the whole problem. Tree reconstruction is a well-worn pattern, so focus on getting the pointer and bounds logic clean rather than learning new material.