Flat Records to a Hierarchical Tree
Reported by candidates from Addepar's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The mistake that sinks a first attempt on this Addepar question is assuming parents show up before their children in the input. Reported in September 2026, this OA hands you flat records and wants a nested JSON forest back as a string. It's a tree-building problem wearing a string-serialization costume. Example 2 puts child "c" ahead of its parent "r" on purpose. If you blank on the structure, StealthCoder is the invisible safety net running during the live OA. But the logic here is short once you see it.
The problem
Convert a flat list of records into a nested JSON forest. Record i has the string fields ids[i], parentIds[i], and texts[i]. An empty parent ID marks a root; otherwise, the record is a child of the record whose ID equals its parent ID.
Preserve input order among roots and among siblings. Return a compact JSON array. Every object must contain the fields id, parent_id, text, and children, in that order. The children value is an array that follows the same rule. Escape strings according to JSON.
Function
buildRecordTree(ids: String[], parentIds: String[], texts: String[]) → String
Examples
Example 1
ids = ["1","2","3","4","5"]
parentIds = ["","","1","2","3"]
texts = ["A","B","C","D","E"]
return = "[{\"id\":\"1\",\"parent_id\":\"\",\"text\":\"A\",\"children\":[{\"id\":\"3\",\"parent_id\":\"1\",\"text\":\"C\",\"children\":[{\"id\":\"5\",\"parent_id\":\"3\",\"text\":\"E\",\"children\":[]}]}]},{\"id\":\"2\",\"parent_id\":\"\",\"text\":\"B\",\"children\":[{\"id\":\"4\",\"parent_id\":\"2\",\"text\":\"D\",\"children\":[]}]}]"
Records 1 and 2 are roots. Record 3 is under 1, record 5 is under 3, and record 4 is under 2.
Example 2
ids = ["c","r","s"]
parentIds = ["r","","r"]
texts = ["first","root","second"]
return = "[{\"id\":\"r\",\"parent_id\":\"\",\"text\":\"root\",\"children\":[{\"id\":\"c\",\"parent_id\":\"r\",\"text\":\"first\",\"children\":[]},{\"id\":\"s\",\"parent_id\":\"r\",\"text\":\"second\",\"children\":[]}]}]"
A child may appear before its parent in the flat input. The two children of r retain their relative input order.
Constraints
0 <= ids.length <= 100000.
The three arrays have equal length.
IDs are unique nonempty printable ASCII strings of length at most 50.
Each parent ID is empty or names exactly one other record.
The parent relationships form a forest.
Text has at most 200 printable ASCII characters.Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is two passes. First, build a map from id to index and a children list per record, appending child indexes in input order. Roots are records with an empty parent ID, also collected in input order. Second, serialize recursively from each root. Order is preserved for free because you append in a single forward scan. The pitfall is a one-pass build that looks up the parent before it exists, which fails when a child precedes its parent. Second pitfall: n can reach 100000, so a deep chain will blow a recursive serializer's stack. Use an iterative DFS with an explicit stack, or make sure your language handles the depth. Also escape quotes and backslashes in text and ids per JSON, and emit fields in the exact order id, parent_id, text, children with no spaces. StealthCoder is your hedge if the iterative serialization trips you up live.
If this hits your live OA and you blank, StealthCoder solves it in seconds, invisible to the proctor.
You can drill Flat Records to a Hierarchical Tree 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 by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Addepar's OA.
Addepar reuses patterns across OAs. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Flat Records to a Hierarchical Tree FAQ
What's the trick to the Addepar flat records to tree problem?+
Don't rely on input order for parents. Scan once to build an id-to-index map and a per-parent list of child indexes in input order. Then serialize from the roots. Because children lists are filled in a forward scan, sibling order is preserved automatically.
Can I build the tree in a single pass?+
Only if you create placeholder nodes for parents you haven't seen yet. It's simpler and less error-prone to do two passes: group children by parent ID first, then walk from the roots. Example 2 has a child before its parent, which breaks naive one-pass lookups.
Will recursion crash on 100000 records?+
It can. The constraints allow a chain 100000 deep, since the forest could be one long line. Use an iterative DFS with an explicit stack and a string builder, or confirm your runtime's recursion limit. Test a long chain mentally before submitting.
How do I get the JSON output format exactly right?+
Emit compact JSON with no whitespace and fields in the order id, parent_id, text, children. Roots have parent_id as an empty string. Leaves have children as []. Escape double quotes and backslashes in text. Build with a string builder, not repeated concatenation.
How do I prepare for this in 48 hours?+
Practice building a tree from parent pointers using a map of parent to children lists. Then write the serializer by hand, both recursive and iterative. Check the edge cases: empty input should return "[]", a single root, and children listed before parents.