@@ -47,33 +47,35 @@ snapshotArr.get(0,0); // 获取 snap_id = 0 的快照中 array[0] 的值,返
47
47
48
48
### 方法一:数组 + 二分查找
49
49
50
- 维护一个数组 ,数组中的每个元素是一个列表,列表中存储的是每次设置的值以及对应的快照编号 。
50
+ 我们维护一个长度为 $\text{length}$ 的数组 ,数组中的每个元素是一个列表,用来存储每次设置的值以及对应的快照 ID 。
51
51
52
- 每次设置值时,将值和快照编号添加到对应索引的列表中 。
52
+ 调用 ` set ` 方法时,将值和快照 ID 添加到对应索引的列表中。时间复杂度 $O(1)$ 。
53
53
54
- 每次获取值时,使用二分查找,找到对应位置第一个大于快照编号 ` snap_id ` 的值,然后返回前一个值即可 。
54
+ 调用 ` snap ` 方法时,我们先将快照 ID 加一,然后返回快照 ID 减一。时间复杂度 $O(1)$ 。
55
55
56
- 时间复杂度上,设置值的时间复杂度为 $O(1)$,快照的时间复杂度为 $O(1)$,获取值的时间复杂度为 $O(\log n)$。
56
+ 调用 ` get ` 方法时,我们使用二分查找找到对应位置的第一个快照 ID 大于 ` snap_id ` 的值,然后返回前一个的值。如果找不到,则返回 0。时间复杂度 $O(\log n)$。
57
+
58
+ 空间复杂度 $O(n)$。
57
59
58
60
<!-- tabs:start -->
59
61
60
62
``` python
61
63
class SnapshotArray :
64
+
62
65
def __init__ (self , length : int ):
63
- self .idx = 0
64
- self .arr = defaultdict( list )
66
+ self .arr = [[] for _ in range (length)]
67
+ self .i = 0
65
68
66
69
def set (self , index : int , val : int ) -> None :
67
- self .arr[index].append((self .idx , val))
70
+ self .arr[index].append((self .i , val))
68
71
69
72
def snap (self ) -> int :
70
- self .idx += 1
71
- return self .idx - 1
73
+ self .i += 1
74
+ return self .i - 1
72
75
73
76
def get (self , index : int , snap_id : int ) -> int :
74
- vals = self .arr[index]
75
- i = bisect_right(vals, (snap_id, inf)) - 1
76
- return 0 if i < 0 else vals[i][1 ]
77
+ i = bisect_left(self .arr[index], (snap_id, inf)) - 1
78
+ return 0 if i < 0 else self .arr[index][i][1 ]
77
79
78
80
79
81
# Your SnapshotArray object will be instantiated and called as such:
@@ -102,17 +104,17 @@ class SnapshotArray {
102
104
}
103
105
104
106
public int get (int index , int snap_id ) {
105
- var vals = arr[index];
106
- int left = 0 , right = vals. size();
107
- while (left < right) {
108
- int mid = (left + right) >> 1 ;
109
- if (vals. get(mid)[0 ] > snap_id) {
110
- right = mid;
107
+ int l = 0 , r = arr[index]. size();
108
+ while (l < r) {
109
+ int mid = (l + r) >> 1 ;
110
+ if (arr[index]. get(mid)[0 ] > snap_id) {
111
+ r = mid;
111
112
} else {
112
- left = mid + 1 ;
113
+ l = mid + 1 ;
113
114
}
114
115
}
115
- return left == 0 ? 0 : vals. get(left - 1 )[1 ];
116
+ -- l;
117
+ return l < 0 ? 0 : arr[index]. get(l)[1 ];
116
118
}
117
119
}
118
120
@@ -129,35 +131,25 @@ class SnapshotArray {
129
131
class SnapshotArray {
130
132
public:
131
133
SnapshotArray(int length) {
132
- idx = 0;
133
- arr = vector<vector<pair<int, int>>>(length);
134
+ arr.resize(length);
134
135
}
135
136
136
137
void set(int index, int val) {
137
- arr[index].push_back({idx , val} );
138
+ arr[index].emplace_back(i , val);
138
139
}
139
140
140
141
int snap () {
141
- return idx ++;
142
+ return i ++;
142
143
}
143
144
144
145
int get(int index, int snap_id) {
145
- auto& vals = arr[index];
146
- int left = 0, right = vals.size();
147
- while (left < right) {
148
- int mid = (left + right) >> 1;
149
- if (vals[mid].first > snap_id) {
150
- right = mid;
151
- } else {
152
- left = mid + 1;
153
- }
154
- }
155
- return left == 0 ? 0 : vals[left - 1].second;
146
+ auto it = upper_bound(arr[index].begin(), arr[index].end(), make_pair(snap_id, INT_MAX));
147
+ return it == arr[index].begin() ? 0 : prev(it)->second;
156
148
}
157
149
158
150
private:
159
151
vector<vector<pair<int, int>>> arr;
160
- int idx ;
152
+ int i = 0 ;
161
153
};
162
154
163
155
/* *
@@ -171,34 +163,31 @@ private:
171
163
172
164
``` go
173
165
type SnapshotArray struct {
174
- idx int
175
- arr [][]pair
166
+ arr [][][ 2 ] int
167
+ i int
176
168
}
177
169
178
170
func Constructor (length int ) SnapshotArray {
179
- return SnapshotArray{0 , make ([][]pair , length)}
171
+ return SnapshotArray{make ([][][ 2 ] int , length), 0 }
180
172
}
181
173
182
174
func (this *SnapshotArray ) Set (index int , val int ) {
183
- this.arr [index] = append (this.arr [index], pair {this.idx , val})
175
+ this.arr [index] = append (this.arr [index], [ 2 ] int {this.i , val})
184
176
}
185
177
186
178
func (this *SnapshotArray ) Snap () int {
187
- this.idx ++
188
- return this.idx - 1
179
+ this.i ++
180
+ return this.i - 1
189
181
}
190
182
191
183
func (this *SnapshotArray ) Get (index int , snap_id int ) int {
192
- vals := this.arr [index]
193
- i := sort.Search (len (vals), func (i int ) bool { return vals[i].i > snap_id })
194
- if i == 0 {
184
+ i := sort.Search (len (this.arr [index]), func (i int ) bool { return this.arr [index][i][0 ] > snap_id }) - 1
185
+ if i < 0 {
195
186
return 0
196
187
}
197
- return vals[i- 1 ]. v
188
+ return this. arr [index][i][ 1 ]
198
189
}
199
190
200
- type pair struct { i, v int }
201
-
202
191
/* *
203
192
* Your SnapshotArray object will be instantiated and called as such:
204
193
* obj := Constructor(length);
@@ -208,6 +197,46 @@ type pair struct{ i, v int }
208
197
*/
209
198
```
210
199
200
+ ``` ts
201
+ class SnapshotArray {
202
+ private arr: [number , number ][][];
203
+ private i: number = 0 ;
204
+ constructor (length : number ) {
205
+ this .arr = Array .from ({ length }, () => []);
206
+ }
207
+
208
+ set(index : number , val : number ): void {
209
+ this .arr [index ].push ([this .i , val ]);
210
+ }
211
+
212
+ snap(): number {
213
+ return this .i ++ ;
214
+ }
215
+
216
+ get(index : number , snap_id : number ): number {
217
+ let [l, r] = [0 , this .arr [index ].length ];
218
+ while (l < r ) {
219
+ const mid = (l + r ) >> 1 ;
220
+ if (this .arr [index ][mid ][0 ] > snap_id ) {
221
+ r = mid ;
222
+ } else {
223
+ l = mid + 1 ;
224
+ }
225
+ }
226
+ -- l ;
227
+ return l < 0 ? 0 : this .arr [index ][l ][1 ];
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Your SnapshotArray object will be instantiated and called as such:
233
+ * var obj = new SnapshotArray(length)
234
+ * obj.set(index,val)
235
+ * var param_2 = obj.snap()
236
+ * var param_3 = obj.get(index,snap_id)
237
+ */
238
+ ```
239
+
211
240
<!-- tabs:end -->
212
241
213
242
<!-- end -->
0 commit comments