Implement a Snapshot Set Iterator
Company: Databricks
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Technical Screen
Quick Answer: This question evaluates understanding of set data structures, iterator and snapshot semantics, and the ability to reason about time and space complexity when providing stable views over mutable collections.
Constraints
- 1 <= len(operations) == len(args) <= 20000
- Values are integers in the range [-10^9, 10^9]
- Every `next(id)` refers to a previously created iterator id
- The sum of the sizes of all created snapshots does not exceed 200000
Examples
Input: (["add","add","iterator","remove","add","next","next","next","contains","contains"], [[1],[2],[],[1],[3],[0],[0],[0],[1],[3]])
Expected Output: [0, 1, 2, None, False, True]
Explanation: The iterator captures {1, 2}. After removing 1 and adding 3, that iterator still returns 1 and 2, then becomes exhausted. The live set ends as {2, 3}.
Input: (["add","add","iterator","add","iterator","remove","next","next","next","next","contains"], [[5],[1],[],[3],[],[1],[0],[1],[0],[1],[1]])
Expected Output: [0, 1, 1, 1, 5, 3, False]
Explanation: Iterator 0 snapshots {1, 5}; iterator 1 snapshots {1, 3, 5}. Removing 1 later does not change either snapshot.
Hints
- A snapshot iterator should not point to the live set directly. Think about what data must be frozen at the moment `iterator()` is called.
- If you store each snapshot separately, each iterator only needs a cursor to know which value `next()` should return.