Topmost Accessible Nodes
Reported by candidates from Figma's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Figma's January 2025 OA has a forest of teams, folders and files, and you return the topmost nodes a user can directly read. If you've got the invite for the next day or two, this is a tree traversal wrapped in access-control language. Parent indices, a per-node user list, and a preorder output requirement. Nothing exotic, but n goes up to 200000, so a sloppy approach dies. The pattern is DFS with a flag for 'already covered.' If you blank mid-assessment, StealthCoder runs invisibly as a safety net and gives you the solution live.
The problem
A hierarchy contains teams, folders, and files. It is represented as a forest of nodes. nodeIds[i] is the unique ID of node i. parent[i] is the parent index, or -1 when node i is a root. readableUsers[i] lists the users with direct read access to node i. Direct access to a node also grants access to every descendant. For userId, return the smallest covering set of nodes: whenever the user has direct access to a node, include that node and do not include any accessible descendant beneath it. Return selected node IDs in forest preorder. Roots and siblings follow their order in the input arrays. Function fewestAccessibleNodes(nodeIds: String[], parent: int[], readableUsers: String[][], userId: String) → String[] Examples Example 1 nodeIds = ["Team1","Folder1","File1","File2","Folder2","Folder3"] parent = [-1,0,1,1,0,4] readableUsers = [[],["A"],["A"],[],[],["A"]] userId = "A" return = ["Folder1","Folder3"] Folder1 covers both files beneath it, so File1 is redundant. Folder3 is in another branch and is also required. Example 2 nodeIds = ["Team1","Folder1","File1","Folder2"] parent = [-1,0,1,0] readableUsers = [["A"],["A"],["A"],[]] userId = "A" return = ["Team1"] Access at the root covers every descendant, so it is the only selected node. Example 3 nodeIds = ["RootA","LeafA","RootB","LeafB"] parent = [-1,0,-1,2] readableUsers = [[],["U"],[],["U"]] userId = "U" return = ["LeafA","LeafB"] Neither root grants access, so each directly readable leaf must be returned. Constraints 1 <= nodeIds.length <= 200000. nodeIds.length == parent.length == readableUsers.length. Node IDs are unique. For every non-root node i, 0 <= parent[i] < i. The total number of direct user entries is at most 200000.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick: a node belongs in the answer only if the user has direct access to it and no ancestor was already selected. So traverse top-down carrying a boolean 'covered'. If covered, skip everything below. If not covered and the user is in readableUsers[i], add the node and mark its subtree covered. Build children lists from parent[], which is guaranteed to satisfy parent[i] < i, so children stay in input order. Roots are the -1 entries in order. Pitfalls: scanning readableUsers lists per node as a list lookup is fine since total entries are at most 200000, but precompute a boolean array once. Recursion depth can hit 200000, so use an iterative stack and push children in reverse to keep preorder. StealthCoder is your hedge if the iterative preorder ordering trips you up live.
Drill it cold or hedge it with StealthCoder. Either way, don't walk into the OA hoping you remember the trick.
You can drill Topmost Accessible Nodes 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. Made for the candidate who got the OA invite this morning and has 72 hours, not six months.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Figma's OA.
Figma reuses patterns across OAs. Made for the candidate who got the OA invite this morning and has 72 hours, not six months. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Topmost Accessible Nodes FAQ
What's the trick in Topmost Accessible Nodes?+
Carry a 'covered' flag down the tree. When you hit a node the user can read and nothing above it was selected, add it and stop descending for selection purposes. Anything beneath is redundant by definition, so one pass handles it.
How hard is this Figma OA question really?+
Medium at most. It's one DFS over a forest with a simple rule. The difficulty is in the details: preorder ordering, roots listed as -1, and avoiding recursion limits at 200000 nodes.
Do I need recursion or can I go iterative?+
Go iterative. Depth can reach 200000 in a chain, which overflows the call stack in many languages. Use an explicit stack and push children in reverse order so they pop in input order, preserving preorder.
How do I check user access efficiently?+
Loop through readableUsers once and set a boolean array hasAccess[i] when userId appears in that node's list. Total entries are capped at 200000, so this is linear. Then the traversal just reads the array.
How do I prep for this in 48 hours?+
Practice building children adjacency lists from a parent array and doing an iterative preorder DFS with state passed down. Then run the three given examples by hand, especially the one with two roots and no root access.