Minimum Snapshots for a Version Tree
Reported by candidates from Adobe's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Adobe reported this one in July 2026, and the input size is the first thing to read. With n up to 2 * 10^5, any approach that tries subsets of snapshots or re-walks ancestors for every version is dead on arrival. It's a tree problem with a greedy, bottom-up answer, and the parent-smaller-than-child guarantee makes it cheap to code. If you blank during the live OA, StealthCoder runs invisibly as a safety net and puts the pattern on screen. Read the pattern below first and you probably won't need it.
The problem
A version-control system stores n + 1 versions as a rooted tree. Version 0 is the root and is always stored as a snapshot. For every version i from 1 through n, parents[i - 1] is its parent and is smaller than i. Reading a version requires replaying edits from its nearest stored ancestor. Its reconstruction cost is the number of tree edges to that ancestor; a stored version has cost 0. You may store additional versions as snapshots. Return the minimum number of additional snapshots needed so that every version has reconstruction cost at most maxCost. Function minimumSnapshots(n: int, maxCost: int, parents: int[]) → int Examples Example 1 n = 5 maxCost = 2 parents = [0,1,2,3,4] return = 1 The versions form one chain. Storing version 3 keeps versions 3, 4, and 5 within cost 2; root snapshot 0 already covers versions 1 and 2. Example 2 n = 3 maxCost = 1 parents = [0,1,1] return = 1 Store version 1. Both children 2 and 3 are then one edge from a stored ancestor. Example 3 n = 6 maxCost = 2 parents = [0,1,2,3,4,5] return = 2 One optimal choice stores versions 1 and 4. Every version is then at most two edges below its nearest stored ancestor. Constraints 1 <= n <= 2 * 10^5. parents.length = n. 0 <= parents[i] <= i for every 0 <= i < n. 0 <= maxCost <= n. Version 0 is already stored and is not counted in the result.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is to process nodes from deepest to shallowest and place a snapshot only when forced. Since parents[i-1] < i, you can loop i from n down to 1 with no recursion and no explicit DFS. For each node keep height[v], the max distance down to an uncovered descendant. Children push their value up as height[child]+1. When a node's height hits maxCost and it isn't the root, store it, count one, and reset its height to cost 0 for the parent's purposes. The root is already stored, so it never counts. Pitfalls: pushing the value upward before finalizing the child, forgetting the root is free, and the maxCost = 0 case, where every non-root node needs a snapshot. Recursion on a 2 * 10^5 chain will overflow the stack, so use the reverse index loop. If you freeze live, StealthCoder is the hedge that shows you this loop.
The honest play: practice the pattern, and have StealthCoder ready for the one you didn't see coming.
You can drill Minimum Snapshots for a Version 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 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
You've seen the question.
Make sure you actually pass Adobe's OA.
Adobe 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.
Minimum Snapshots for a Version Tree FAQ
What's the trick for Adobe's Minimum Snapshots problem?+
Go bottom-up and be greedy. Snapshot a node only when its deepest uncovered descendant would otherwise exceed maxCost. Delaying the snapshot as high as possible covers the most nodes, which is why the greedy choice is optimal. Count one each time you place one.
Do I need recursion or DFS for this?+
No. Every parent index is smaller than its child, so looping i from n down to 1 visits children before parents. That gives you a post-order without recursion, and it avoids stack overflow on a 2 * 10^5 deep chain.
How hard is this really?+
Medium. The idea is a known tree greedy, and the code is about ten lines. The difficulty is realizing brute force fails at this input size and handling the root and maxCost = 0 correctly.
What edge cases should I test?+
Test maxCost = 0, where every non-root version needs its own snapshot. Test a single chain like the examples, a star where the root covers everything, and n = 1. Also confirm the root is never counted in the result.
How do I prepare for this in 48 hours?+
Practice two or three bottom-up tree greedies where you track a height or state per node and reset it when you place something. Write the reverse-index loop until it's automatic. Then trace the three given examples by hand before you submit.