The following is my first solution, very easy to understand, but brute force:
For every snapshot, we clone the whole array.
Time complexity of snap(): O(n), n is the length of the array.
Space complexity of snap(): O(n*k), n is the length of the array, k is the snap times.
class SnapshotArray { private List<int[]> snaps = new ArrayList<>(); private int[] array; public SnapshotArray(int length) { array = new int[length]; } public void set(int index, int val) { array[index]=val; } public int snap() { int[] snapshotArray = new int[array.length]; for(int i=0;i<array.length;i++){ snapshotArray[i]=array[i]; } snaps.add(snapshotArray); return snaps.size()-1; } public int get(int index, int snap_id) { int[] snapshotArray = snaps.get(snap_id); return snapshotArray[index]; } }
Intead of storing the whole array as a snapshot, using TreeMaps to store every snapshots of every element in the array.
Following are some useful methods of TreeMap:
public Map.Entry<K,V> floorEntry(K key)
Returns:an entry with the greatest key less than or equal to key
, or null
if there is no such key
Returns:the greatest key less than or equal to key
, or null
if there is no such key
public Map.Entry<K,V> firstEntry()
Returns:an entry with the least key, or null
if this map is empty
public K firstKey()
Returns:the first (lowest) key currently in this map
Time complexity of snap(): O(1)
Space complexity of snap(): O(n*k), but k is average snaps times of elements.
class SnapshotArray { private List<TreeMap<Integer, Integer>> snaps; private int snapId = 0; public SnapshotArray(int length) { snaps = new ArrayList<>(); for(int i=0;i<length;i++){ snaps.add(new TreeMap<>()); snaps.get(i).put(0, 0); } } public void set(int index, int val) { snaps.get(index).put(snapId, val); } public int snap() { return snapId++; } public int get(int index, int snap_id) { return snaps.get(index).floorEntry(snap_id).getValue(); } }
We can also use a TreeMap array to replace the List:
class SnapshotArray { private TreeMap<Integer, Integer>[] snaps; private int snapId = 0; public SnapshotArray(int length) { snaps = new TreeMap[length]; for(int i=0;i<length;i++){ snaps[i]=new TreeMap<>(); snaps[i].put(0, 0); } } public void set(int index, int val) { snaps[index].put(snapId, val); } public int snap() { return snapId++; } public int get(int index, int snap_id) { return snaps[index].floorEntry(snap_id).getValue(); } }