问题:
数组快照问题:
1. 初始化长度为length的数组:SnapshotArray
2. 向数组第x位插入数字val:set(int index, int val)
3. 对当前状态对数组做快照(返回值位当前快照id):snap()
4. 获取快照id为snap_id时,数组第index位上的数值,并返回:get(int index, int snap_id)
Example 1: Input: ["SnapshotArray","set","snap","set","get"] [[3],[0,5],[],[0,6],[0,0]] Output: [null,null,0,null,5] Explanation: SnapshotArray snapshotArr = new SnapshotArray(3); // set the length to be 3 snapshotArr.set(0,5); // Set array[0] = 5 snapshotArr.snap(); // Take a snapshot, return snap_id = 0 snapshotArr.set(0,6); snapshotArr.get(0,0); // Get the value of array[0] with snap_id = 0, return 5 Constraints: 1 <= length <= 50000 At most 50000 calls will be made to set, snap, and get. 0 <= index < length 0 <= snap_id < (the total number of times we call snap()) 0 <= val <= 10^9
解法:
构造数据结构 vector<map<int, int>> arr;
数组表示,快照对象数组的每一位
数组值记录:key:快照id,value:对应快照时的当前位置数组数值。{key:value}
以及 记录当前最新的快照id:snap_id
1. 初始化:
resize初始化数组 arr,
且对快照id为0的,所有数组位置数值初始化为0。
2. 向数组第x位插入数字val:set(int index, int val)
找到数组index位,对当前快照id:key=snap_id,的值赋值为 val
3. 对当前状态对数组做快照(返回值位当前快照id):snap()
下次快照id:snap_id++,返回当前id:snap_id-1
4. 获取快照id为snap_id时,数组第index位上的数值,并返回:get(int index, int snap_id)
使用二分查找,在数组index位上,找到上界为snap_id(>snap_id的游标<开区间")">),
将游标左移一位,就刚好是snap_id。
代码参考:
1 class SnapshotArray { 2 public: 3 vector<map<int, int>> arr; 4 int snap_id=0; 5 SnapshotArray(int length) { 6 arr.resize(length); 7 for(int i=0; i<length; i++){ 8 arr[i][0]=0; 9 } 10 } 11 12 void set(int index, int val) { 13 arr[index][snap_id]=val; 14 } 15 16 int snap() { 17 snap_id++; 18 return snap_id-1; 19 } 20 21 int get(int index, int snap_id) { 22 auto it=arr[index].upper_bound(snap_id); 23 it--; 24 return it->second; 25 } 26 }; 27 28 /** 29 * Your SnapshotArray object will be instantiated and called as such: 30 * SnapshotArray* obj = new SnapshotArray(length); 31 * obj->set(index,val); 32 * int param_2 = obj->snap(); 33 * int param_3 = obj->get(index,snap_id); 34 */