题目地址:
https://leetcode.com/problems/snapshot-array/
要求实现一个数据结构,可以做如下操作:
1、SnapshotArray(int length)
以一个长度
l
l
l初始化其为一个类似数组的数据结构,每个元素初始值为
0
0
0;
2、void set(index, val)
将某个位置设为给定值
v
v
v;
3、int snap()
将当前数组保存为快照,并返回当前的版本号,版本号等于;
4、int get(index, snap_id)
返回第snap_id
个版本的index
位置的值。
法1:开个vector,然后每个位置把每个版本的历史值都存起来,get的时候按照版本号二分即可。在set的时候可以检查一下是否是最新的快照,如果是的话可以直接修改而不用多存一个pair。代码如下:
class SnapshotArray {
public:
#define x first
#define y second
vector<vector<pair<int, int>>> vs;
int snap_id;
SnapshotArray(int length) {
snap_id = 0;
vs.resize(length, {{-1, 0}});
}
void set(int index, int val) {
auto &v = vs[index];
if (v.back().x == snap_id) v.back().y = val;
else v.push_back({snap_id, val});
}
int snap() {
return snap_id++;
}
int get(int index, int snap_id) {
// 一定要取引用,减少拷贝
auto &v = vs[index];
int l = 0, r = v.size() - 1;
while (l < r) {
int mid = l + (r - l + 1 >> 1);
if (v[mid].x <= snap_id) l = mid;
else r = mid - 1;
}
return v[l].y;
}
};
初始化时间复杂度 O ( l ) O(l) O(l),set和snap复杂度 O ( 1 ) O(1) O(1),get复杂度 O ( log v ) O(\log v) O(logv), v v v是get的位置有多少个版本,空间 O ( l ) O(l) O(l)。
法2:可以参考可持久化Trie的做法,参考https://blog.csdn.net/qq_46105170/article/details/119029015。代码如下:
class SnapshotArray {
public:
struct Node {
Node* ne[10];
int val;
Node(int x) : val(x) { fill(ne, ne + 10, nullptr); }
Node() : Node(0) {}
};
vector<Node*> v;
SnapshotArray(int length) { v.push_back(new Node()); }
void set(int index, int val) {
string s = to_string(index);
auto *p = v.back(), *q = p;
for (char ch : s) {
int idx = ch - '0';
if (!p->ne[idx]) {
p->ne[idx] = new Node();
p = p->ne[idx];
} else {
q = p->ne[idx];
p->ne[idx] = new Node(q->val);
p = p->ne[idx];
copy(q->ne, q->ne + 10, p->ne);
}
}
p->val = val;
}
int snap() {
auto *p = new Node(), *q = v.back();
copy(q->ne, q->ne + 10, p->ne);
v.push_back(p);
return v.size() - 2;
}
int get(int index, int snap_id) {
string s = to_string(index);
auto* p = v[snap_id];
for (char ch : s) {
int idx = ch - '0';
if (!p->ne[idx]) return 0;
p = p->ne[idx];
}
return p->val;
}
};
每个操作时间复杂度 O ( 1 ) O(1) O(1),空间与操作次数成正比。