class SnapshotArray:
"""
main idea: avoid redundent array copy in other unchanged indexes, use a list to record each snap_id's value according to each index; use Binary Search to lookup history snap_id and its corresponding value
"""
# tc O(N) sc O(N)
def __init__(self, n: int):
self.snap_id = 0
self.idx_idval = {i:[(0,0)] for i in range(n)} # idx: [[snap_id:val],....]
# tc O(1)
def set(self, index: int, val: int) -> None:
if self.snap_id == self.idx_idval[index][-1][0]:
self.idx_idval[index][-1] = [self.snap_id,val]
else:
self.idx_idval[index].append((self.snap_id,val))
def snap(self) -> int:
self.snap_id += 1
return self.snap_id - 1
# tc O(lgS * M) S: number of snap calls; M: number of get calls
def get(self, index: int, snap_id: int) -> int:
A = self.idx_idval[index]
idx = bisect.bisect_left(A,(snap_id,)) # search for [snap_id] if using [snap_id,val] as unit in A
#print(A,idx)
if idx >= len(A):
return A[-1][1]
else:
return A[idx][1] if A[idx][0] == snap_id else A[idx-1][1]
# Your SnapshotArray object will be instantiated and called as such:
# obj = SnapshotArray(length)
# obj.set(index,val)
# param_2 = obj.snap()
# param_3 = obj.get(index,snap_id)