Implement a Snapshot Set Iterator
Company: Databricks
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Technical Screen
Overview: 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.
Read the full Databricks Software Engineer interview experience this question came from
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.