AlgoInsight

DSA problem

Snapshot Array

MediumData Structure DesignPattern: Data Structure Designtop300AmazonGoogleMicrosoftUberTikTok

Implement a SnapshotArray of fixed length that supports point updates and full-array snapshots. The constructor takes a length and initializes every index to 0. set(index, val) updates a single cell. snap() takes a snapshot of the entire array and returns its snap-id — the first snapshot returns 0, the next returns 1, and so on. get(index, snapId) returns the value of array[index] at the moment snapshot snapId was taken.

A literal implementation that copies the entire array on every snap() is correct but catastrophically slow: with length up to 50,000 and up to 50,000 snapshots, the worst case is 2.5×10^9 array copies. We need snap() to be O(1) and get / set to stay cheap, which rules out any full-array materialization.

The standard trick is per-index versioning. Keep one list per index — call it the history of that cell — where each entry is a pair (snapId, value). set(index, val) simply appends (snapId, val) to that index's history (or overwrites the last entry if it was made at the current snapId — an optional optimization). snap() is reduced to incrementing a counter. get(index, snapId) binary-searches the index's history for the largest (s, v) whose s <= snapId and returns v, defaulting to 0 if no history exists.

This gives O(1) snap, O(1) amortized set, and O(log K) get where K is the number of writes to that specific index — far smaller than the array length. Total memory is proportional to the number of writes, not the product of array length × snapshots, which is the whole point of the design.

Examples

Example 1
Input: SnapshotArray(3); set(0, 5); snap(); set(0, 6); get(0, 0)
Output: 5
Explanation: snap() returns 0; the later set(0, 6) is recorded after the snapshot, so get(0, 0) reports the value at snap-id 0, which is 5.
Example 2
Input: set(0, 4); snap(); set(0, 10); snap(); set(1, 7); get(0, 1)
Output: 10
Explanation: At snap-id 1 the cell index 0 held value 10. The later write to index 1 does not affect index 0.
Example 3
Input: SnapshotArray(2); snap(); snap(); get(1, 1)
Output: 0
Explanation: Index 1 was never written, so any snapshot reports the default value 0.

Constraints

3 hints and a full solution walkthrough with step-by-step visualizations are available in the practice editor.

designarraybinary-searchhash-table

Browse all DSA problems