Implement Snapshot Iterator Without Order Guarantees
Company: Databricks
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates data-structure design and iterator semantics—specifically snapshot iteration over a mutable, set-like collection without order guarantees—and tests skills in implementing mutation-isolated iteration and analyzing time and space complexity; it belongs to the Coding & Algorithms domain and emphasizes practical implementation.
Constraints
- 0 <= len(operations) <= 2 * 10^5
- -10^9 <= value <= 10^9
- All iterator ids passed to `hasNext` and `drain` are valid.
- The sum of collection sizes over all `snapshot` operations is at most 2 * 10^5.
Examples
Input: [('add', 5), ('add', 1), ('add', 5), ('contains', 1), ('contains', 2), ('snapshot',), ('remove', 1), ('add', 3), ('contains', 1), ('hasNext', 0), ('drain', 0), ('hasNext', 0)]
Expected Output: [True, False, 0, False, True, [1, 5], False]
Explanation: The duplicate add of 5 is ignored. Snapshot 0 captures {5, 1}. Later removing 1 and adding 3 changes the live collection but not the snapshot.
Input: [('add', 10), ('add', 20), ('snapshot',), ('remove', 10), ('add', 30), ('snapshot',), ('add', 40), ('contains', 10), ('drain', 0), ('hasNext', 0), ('drain', 1), ('snapshot',), ('drain', 2)]
Expected Output: [0, 1, False, [10, 20], False, [20, 30], 2, [20, 30, 40]]
Explanation: Three different snapshots see three different collection states: {10,20}, then {20,30}, then {20,30,40}.
Hints
- If order does not matter, store current elements in a dynamic array plus a hash map from value to index. You can remove in O(1) average time by swapping the target with the last element and popping.
- A snapshot iterator can simply own a copy of the current array. Then future mutations affect only the live collection, not older snapshots.