具体思路:
二分卡了很久,这里简单说一下这种情况,手写二分恶心的情况基本上都碰到了;
首先明确一下,vector<vector<pair<int,int>>>第一层是index,第二层是pair,first为快照id,second为具体元素;
由于这种方法的特殊性,会导致某一时刻的快照,如果后续没有新改变,则不会保存;
例如,快照索引:[3,5,6];
代表,0,1,2,为空,4和3的快照相同,因此二分的时候要格外注意;
对于寻找idx的情况,应该寻找两种:
- 如果为idx存在;
- 如果idx不存在,应该寻找最后一个小于idx的情况,此时表现为寻找第一个大于idx的元素;
针对于第二种情况,会分三种,第一种情况可以合并为第三种;
- 例如[2,3,4],idx=1,此时所有元素都大于idx,此时减1为-1,直接返回初始值0;
- 例如[2,4,5],idx=3,此时寻找到4,idx=2 ,减1就是答案;
- 例如[2,4,5],idx=6,此时寻找到最大值,但是判断idx大于该元素,直接返回;
具体代码:
class SnapshotArray {
public:
SnapshotArray(int length) {
time=0;
snaps.resize(length);
}
void set(int index, int val) {
change[index]=val;
}
int snap() {
for(auto [a,b]:change){
snaps[a].push_back({time,b});
}
change.clear();
time++;
return time-1;
}
int get(int index, int snap_id) {
auto& vec=snaps[index];
if(vec.size()==0)
return 0;
int l=0,r=vec.size()-1;
while(l<r){
int mid=l+(r-l)/2;
if(vec[mid].first<=snap_id){
l=mid+1;
}else{
r=mid;
}
}
if(vec[l].first<=snap_id)
return vec[l].second;
else{
if(l==0)
return 0;
else
return vec[l-1].second;
}
return 0;
}
private:
unordered_map<int, int>change;
vector<vector<pair<int,int>>>snaps;
int time;
};
/*
0,1,2
1,2,3
*/
/**
* Your SnapshotArray object will be instantiated and called as such:
* SnapshotArray* obj = new SnapshotArray(length);
* obj->set(index,val);
* int param_2 = obj->snap();
* int param_3 = obj->get(index,snap_id);
*/