Problem Description
Design a data structure called SnapshotArray that simulates an array which supports setting values, taking snapshots, and retrieving historical values based on a snapshot identifier. Initially, every element is 0. The methods include set(index, val) to update an element, snap() to record the current state of the array and return a snapshot id, and get(index, snap_id) to fetch the value at a given index from a particular snapshot.
Key Insights
- Use per-index storage to maintain history of changes; record only when updates occur.
- Each index stores a list of (snap_id, value) pairs, sorted by snap_id.
- Utilize binary search during a get operation to efficiently find the most recent update not exceeding the provided snap_id.
- Keep a current snap_id counter and update it with each snap() call.
Space and Time Complexity
Time Complexity:
- set: O(1) (amortized)
- snap: O(1)
- get: O(log S), where S is the number of times an index was set (binary search over updates) Space Complexity: O(n + total number of set operations), since we store only updates per index.
Solution
We maintain a history for each array index as a list of pairs with each pair containing a snapshot id and its corresponding value. When setting a value, if the latest snapshot id in the history for that index matches the current snap_id, update the value. Otherwise, append a new (snap_id, value) pair. The snap() method will increment the snap_id counter and return the previous counter. The get() method performs a binary search on the history list for the given index to locate the most recent update where snap_id is less than or equal to the queried snap_id.