题目:
实现支持下列接口的「快照数组」- SnapshotArray:
SnapshotArray(int length)- 初始化一个与指定长度相等的 类数组 的数据结构。初始时,每个元素都等于 0。void set(index, val)- 会将指定索引index处的元素设置为val。int snap()- 获取该数组的快照,并返回快照的编号snap_id(快照号是调用snap()的总次数减去1)。int get(index, snap_id)- 根据指定的snap_id选择快照,并返回该快照指定索引index的值。
算法:
方法一:数组
type SnapshotArray struct {
Arr [][][]int
SnapID int
}
func Constructor(length int) SnapshotArray {
s := SnapshotArray{
Arr: make([][][]int, length),
}
for i := range s.Arr {
s.Arr[i] = make([][]int, 0)
}
return s
}
func (this *SnapshotArray) Set(index int, val int) {
this.Arr[index] = append(this.Arr[index], []int{this.SnapID, val})
}
// 执行这个命令snap才会+1
func (this *SnapshotArray) Snap() int {
this.SnapID ++
return this.SnapID - 1
}
func (this *SnapshotArray) Get(index int, snap_id int) int {
list := this.Arr[index]
left, right := -1, len(list) - 1
for left < right {
mid := left + (right - left) / 2 + 1
if list[mid][0] <= snap_id {
left = mid
} else {
right = mid - 1
}
}
// snap(),然后set,会导致snap_id=0时,list为空
if left == -1 {
return 0
}
return list[left][1]
}
/**
* Your SnapshotArray object will be instantiated and called as such:
* obj := Constructor(length);
* obj.Set(index,val);
* param_2 := obj.Snap();
* param_3 := obj.Get(index,snap_id);
*/
方法二:初始化数组
type SnapshotArray struct {
Arr [][][]int
SnapID int
}
func Constructor(length int) SnapshotArray {
s := SnapshotArray{
Arr: make([][][]int, length),
}
for i := range s.Arr {
s.Arr[i] = [][]int{[]int{0, 0}}
}
return s
}
func (this *SnapshotArray) Set(index int, val int) {
this.Arr[index] = append(this.Arr[index], []int{this.SnapID, val})
}
// 执行这个命令snap才会+1
func (this *SnapshotArray) Snap() int {
this.SnapID ++
return this.SnapID - 1
}
func (this *SnapshotArray) Get(index int, snap_id int) int {
list := this.Arr[index]
left, right := 0, len(list) - 1
for left < right {
mid := (right + left) / 2 + 1
if list[mid][0] <= snap_id {
left = mid
} else {
right = mid - 1
}
}
// // snap(),然后set,会导致snap_id=0时,list为空
// if len(list[left]) == 0 {
// return 0
// }
return list[left][1]
}
/**
* Your SnapshotArray object will be instantiated and called as such:
* obj := Constructor(length);
* obj.Set(index,val);
* param_2 := obj.Snap();
* param_3 := obj.Get(index,snap_id);
*/