Skip to content

Commit 1f8ec5f

Browse files
authored
feat: update solutions to lc problems: No.1146,2639 (doocs#2649)
* No.1146.Snapshot Array * No.2639.Find the Width of Columns of a Grid
1 parent 367e634 commit 1f8ec5f

File tree

13 files changed

+244
-166
lines changed

13 files changed

+244
-166
lines changed

solution/1100-1199/1146.Snapshot Array/README.md

+77-48
Original file line numberDiff line numberDiff line change
@@ -47,33 +47,35 @@ snapshotArr.get(0,0); // 获取 snap_id = 0 的快照中 array[0] 的值,返
4747

4848
### 方法一:数组 + 二分查找
4949

50-
维护一个数组,数组中的每个元素是一个列表,列表中存储的是每次设置的值以及对应的快照编号
50+
我们维护一个长度为 $\text{length}$ 的数组,数组中的每个元素是一个列表,用来存储每次设置的值以及对应的快照 ID
5151

52-
每次设置值时,将值和快照编号添加到对应索引的列表中
52+
调用 `set` 方法时,将值和快照 ID 添加到对应索引的列表中。时间复杂度 $O(1)$
5353

54-
每次获取值时,使用二分查找,找到对应位置第一个大于快照编号 `snap_id` 的值,然后返回前一个值即可
54+
调用 `snap` 方法时,我们先将快照 ID 加一,然后返回快照 ID 减一。时间复杂度 $O(1)$
5555

56-
时间复杂度上,设置值的时间复杂度为 $O(1)$,快照的时间复杂度为 $O(1)$,获取值的时间复杂度为 $O(\log n)$。
56+
调用 `get` 方法时,我们使用二分查找找到对应位置的第一个快照 ID 大于 `snap_id` 的值,然后返回前一个的值。如果找不到,则返回 0。时间复杂度 $O(\log n)$。
57+
58+
空间复杂度 $O(n)$。
5759

5860
<!-- tabs:start -->
5961

6062
```python
6163
class SnapshotArray:
64+
6265
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
6568

6669
def set(self, index: int, val: int) -> None:
67-
self.arr[index].append((self.idx, val))
70+
self.arr[index].append((self.i, val))
6871

6972
def snap(self) -> int:
70-
self.idx += 1
71-
return self.idx - 1
73+
self.i += 1
74+
return self.i - 1
7275

7376
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]
7779

7880

7981
# Your SnapshotArray object will be instantiated and called as such:
@@ -102,17 +104,17 @@ class SnapshotArray {
102104
}
103105

104106
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;
111112
} else {
112-
left = mid + 1;
113+
l = mid + 1;
113114
}
114115
}
115-
return left == 0 ? 0 : vals.get(left - 1)[1];
116+
--l;
117+
return l < 0 ? 0 : arr[index].get(l)[1];
116118
}
117119
}
118120

@@ -129,35 +131,25 @@ class SnapshotArray {
129131
class SnapshotArray {
130132
public:
131133
SnapshotArray(int length) {
132-
idx = 0;
133-
arr = vector<vector<pair<int, int>>>(length);
134+
arr.resize(length);
134135
}
135136

136137
void set(int index, int val) {
137-
arr[index].push_back({idx, val});
138+
arr[index].emplace_back(i, val);
138139
}
139140

140141
int snap() {
141-
return idx++;
142+
return i++;
142143
}
143144

144145
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;
156148
}
157149

158150
private:
159151
vector<vector<pair<int, int>>> arr;
160-
int idx;
152+
int i = 0;
161153
};
162154

163155
/**
@@ -171,34 +163,31 @@ private:
171163

172164
```go
173165
type SnapshotArray struct {
174-
idx int
175-
arr [][]pair
166+
arr [][][2]int
167+
i int
176168
}
177169

178170
func Constructor(length int) SnapshotArray {
179-
return SnapshotArray{0, make([][]pair, length)}
171+
return SnapshotArray{make([][][2]int, length), 0}
180172
}
181173

182174
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})
184176
}
185177

186178
func (this *SnapshotArray) Snap() int {
187-
this.idx++
188-
return this.idx - 1
179+
this.i++
180+
return this.i - 1
189181
}
190182

191183
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 {
195186
return 0
196187
}
197-
return vals[i-1].v
188+
return this.arr[index][i][1]
198189
}
199190

200-
type pair struct{ i, v int }
201-
202191
/**
203192
* Your SnapshotArray object will be instantiated and called as such:
204193
* obj := Constructor(length);
@@ -208,6 +197,46 @@ type pair struct{ i, v int }
208197
*/
209198
```
210199

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+
211240
<!-- tabs:end -->
212241

213242
<!-- end -->

0 commit comments

Comments
 (0)