Question
Implement a SnapshotArray that supports the following interface:
SnapshotArray(int length)initializes an array-like data structure with the given length. Initially, each element equals 0.void set(index, val)sets the element at the givenindexto be equal toval.int snap()takes a snapshot of the array and returns thesnap_id: the total number of times we calledsnap()minus1.int get(index, snap_id)returns the value at the givenindex, at the time we took the snapshot with the givensnap_id
Idea
- Relatively simple problem but the trick here is to not overflow our memory limits.
- We cannot just maintain the entire array for every snapshot but we don’t need to since what we’re primarily concerned about is the history of our changes.
- We implement a list where each index in the list is a
snap_idcontaining a hash map of the form{index: value} - On
get(), we start at a givensnap_idand see if ourindexis in our hash map, searching linearly backwardsO(snap_id), until, we find a value for ourindex, otherwise we return the default value of0
Optimal solution
- The optimal solution uses binary search instead of just checking all indices in reverse order
- We use an array of array arrays as our data structure here
self.snapshotArray = [[[0, 2], [1, 2]]]ofself.snapshotArray[index][[snap_id][value]] - The twist here is when we set, we want to make sure we overwrite the most recent value if we have the same snap_id so we don’t make multiple entries in our array
self.snapshotArray[index][-1][1] = valifself.snapshotArray[index][-1][0] == snap_id - Then in get, we can use a binary search to get our value because we are inherently sorted by our snap_id so this will be more efficient rather than scanning
- When we run binary search, we want to store the last value on updating
linto res which we return if we never find the seen value