-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsnapshot_arr.go
63 lines (55 loc) · 1.94 KB
/
snapshot_arr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package problem1146
import "sort"
/*
Implement a SnapshotArray that supports the following interface:
SnapshotArray(int length) initializes an array-like data structure with the given length. Initially, each element equals 0.
void set(index, val) sets the element at the given index to be equal to val.
int snap() takes a snapshot of the array and returns the snap_id: the total number of times we called snap() minus 1.
int get(index, snap_id) returns the value at the given index, at the time we took the snapshot with the given snap_id
*/
type SnapVal struct {
Id int
Val int
}
type SnapshotArray struct {
// Snaps[i] represents all the values in index i at different snapshots
Snaps [][]*SnapVal
Size int
Cur int
}
func Constructor(length int) SnapshotArray {
snap := SnapshotArray{
Snaps: make([][]*SnapVal, length),
Size: length,
Cur: 0,
}
// Seeding the first snapshot with 0's
for i := 0; i < length; i++ {
snap.Snaps[i] = []*SnapVal{{0, 0}}
}
return snap
}
func (this *SnapshotArray) Set(index int, val int) {
if this.Snaps[index][len(this.Snaps[index])-1].Id == this.Cur {
// If snap id is the same as the last id (There was no snap), change the value
this.Snaps[index][len(this.Snaps[index])-1].Val = val
} else {
// If snap id is different (There was a snap), add a new snap value
this.Snaps[index] = append(this.Snaps[index], &SnapVal{this.Cur, val})
}
}
func (this *SnapshotArray) Snap() int {
this.Cur++
return this.Cur - 1
}
func (this *SnapshotArray) Get(index int, snap_id int) int {
// List of snap values at the given index
indexSnap := this.Snaps[index]
// Binary search showing the smallest index with bigger id
latestIndex := sort.Search(len(indexSnap), func(i int) bool { return indexSnap[i].Id >= snap_id })
if latestIndex >= len(indexSnap) || indexSnap[latestIndex].Id != snap_id {
// Edge cases for when index is overflowing or not found
latestIndex--
}
return this.Snaps[index][latestIndex].Val
}