Snapshot Array
Description
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 givenindex
to be equal toval
.int snap()
takes a snapshot of the array and returns thesnap_id
: the total number of times we calledsnap()
minus1
.int get(index, snap_id)
returns the value at the givenindex
, at the time we took the snapshot with the givensnap_id
Example 1:
Input: ["SnapshotArray","set","snap","set","get"] [[3],[0,5],[],[0,6],[0,0]] Output: [null,null,0,null,5] Explanation: SnapshotArray snapshotArr = new SnapshotArray(3); // set the length to be 3 snapshotArr.set(0,5); // Set array[0] = 5 snapshotArr.snap(); // Take a snapshot, return snap_id = 0 snapshotArr.set(0,6); snapshotArr.get(0,0); // Get the value of array[0] with snap_id = 0, return 5
Constraints:
1 <= length <= 50000
- At most
50000
calls will be made toset
,snap
, andget
. 0 <= index < length
0 <= snap_id <
(the total number of times we callsnap()
)0 <= val <= 10^9
Solution(javascript)
// /**
// * @param {number} length
// */
// const SnapshotArray = function (length) {
// this.snap_id = 0
// this.list = new Array(length).fill(0).map(() => ({
// [this.snap_id]: 0,
// }))
// }
// /** O(1)
// * @param {number} index
// * @param {number} val
// * @return {void}
// */
// SnapshotArray.prototype.set = function (index, val) {
// this.list[index][this.snap_id] = val
// }
// /** O(1)
// * @return {number}
// */
// SnapshotArray.prototype.snap = function () {
// this.snap_id += 1
// return this.snap_id - 1
// }
// /** 之前的解法是 O(snap_id) 我们可以做的更好, 把它做到 O(log(snapLength)) 或者
// * @param {number} index
// * @param {number} snap_id
// * @return {number}
// */
// SnapshotArray.prototype.get = function (index, snap_id) {
// if (this.list[index][snap_id] === undefined) {
// const keys = Object.keys(this.list[index]).map(key => Number(key)).sort((a, b) => a - b)
// console.log(keys)
// for (let i = keys.length - 1; i >= 0; i--) {
// if (keys[i] <= snap_id) {
// return this.list[index][keys[i]]
// }
// }
// return 0
// }
// return this.list[index][snap_id]
// }
// SnapshotArray.prototype.get = function (index, snap_id) {
// let current = snap_id
// while (this.list[index][current] === undefined) {
// current -= 1
// }
// return this.list[index][current]
// }
/** 在 JS 里进一步优化,不初始化
* @param {number} length
*/
const SnapshotArray = function (length) {
this.snap_id = 0
this.list = []
}
/** O(1)
* @param {number} index
* @param {number} val
* @return {void}
*/
SnapshotArray.prototype.set = function (index, val) {
this.list[index] = this.list[index] || []
this.list[index][this.snap_id] = val
}
/** O(1)
* @return {number}
*/
SnapshotArray.prototype.snap = function () {
this.snap_id += 1
return this.snap_id - 1
}
/** 之前的解法是 O(snap_id) 我们可以做的更好, 把它做到 O(log(snapLength)) 或者
* @param {number} index
* @param {number} snap_id
* @return {number}
*/
SnapshotArray.prototype.get = function (index, snap_id) {
if (this.list[index] === undefined) {
return 0
}
if (this.list[index][snap_id] === undefined) {
const keys = Object.keys(this.list[index]).map(key => Number(key)).sort((a, b) => a - b)
for (let i = keys.length - 1; i >= 0; i--) {
if (keys[i] <= snap_id) {
return this.list[index][keys[i]]
}
}
return 0
}
return this.list[index][snap_id]
}