Snapshot Array - Problem
Design and implement a SnapshotArray that efficiently stores historical versions of an array. Imagine building a version control system for an array where you can take snapshots and later retrieve values from any previous snapshot.
Your
•
•
•
•
The key challenge: How do you efficiently store snapshots without using excessive memory when only a few elements change between snapshots?
Your
SnapshotArray class must support:•
SnapshotArray(int length) - Initialize array with given length, all elements start as 0•
set(index, val) - Update element at given index to val•
snap() - Take a snapshot and return snapshot ID (starting from 0)•
get(index, snap_id) - Retrieve value at index from a specific snapshotThe key challenge: How do you efficiently store snapshots without using excessive memory when only a few elements change between snapshots?
Input & Output
example_1.py — Basic Operations
$
Input:
["SnapshotArray","set","snap","set","get"]
[[3],[0,5],[],[0,6],[0,0]]
›
Output:
[null,null,0,null,5]
💡 Note:
Initialize array of length 3: [0,0,0]. Set index 0 to 5: [5,0,0]. Take snapshot 0. Set index 0 to 6: [6,0,0]. Get value at index 0 from snapshot 0, which returns 5 (the value before the second set operation).
example_2.py — Multiple Snapshots
$
Input:
["SnapshotArray","set","snap","set","snap","get","get"]
[[2],[1,10],[],[1,20],[],[1,0],[1,1]]
›
Output:
[null,null,0,null,1,10,20]
💡 Note:
Initialize array [0,0]. Set index 1 to 10: [0,10]. Snapshot 0. Set index 1 to 20: [0,20]. Snapshot 1. get(1,0) returns 10, get(1,1) returns 20.
example_3.py — No Changes Edge Case
$
Input:
["SnapshotArray","snap","get","get"]
[[4],[],[0,0],[2,0]]
›
Output:
[null,0,0,0]
💡 Note:
Initialize array [0,0,0,0]. Take snapshot 0 immediately. Both get(0,0) and get(2,0) return 0 since no values were changed from the initial state.
Constraints
- 1 ≤ length ≤ 5 × 104
- 0 ≤ index < length
- 0 ≤ val ≤ 109
- 0 ≤ snap_id < (number of times snap() is called)
- At most 5 × 104 calls will be made to set, snap, and get
Visualization
Tap to expand
Understanding the Visualization
1
Initialize
Each array index maintains its own timeline starting with snapshot 0, value 0
2
Track Changes
When set() is called, append the change to that index's timeline
3
Snapshot
Increment snapshot counter - no copying needed!
4
Retrieve
Binary search the timeline to find the latest change at or before target snapshot
Key Takeaway
🎯 Key Insight: By storing only the changes (like Git diffs) and using binary search to find historical values, we achieve optimal space efficiency while maintaining fast query performance. This is a classic example of trading a small amount of query time complexity for massive space savings.
💡
Explanation
AI Ready
💡 Suggestion
Tab
to accept
Esc
to dismiss
// Output will appear here after running code