对于这一题刚开始的考虑,用set就可以解决了,set的add has remove操作的时间复杂度都是1,但是在随机获取数字这个上面,我的操作的时间复杂度不是1,而是n。
错误的题解
在getRandom方法处理的时候存在问题,
在每次获取随机数的时候都会创建一个数组,这个的时间、空间复杂度是n,所以不符合题目条件
var RandomizedSet = function () {
this.set = new Set()
};
/**
* @param {number} val
* @return {boolean}
*/
RandomizedSet.prototype.insert = function (val) {
if (this.set.has(val)) {
return false
} else {
this.set.add(val)
return true
}
};
/**
* @param {number} val
* @return {boolean}
*/
RandomizedSet.prototype.remove = function (val) {
if (this.set.has(val)) {
this.set.delete(val)
return true
} else {
return false
}
};
/**
* @return {number}
*/
RandomizedSet.prototype.getRandom = function () {
let odd = Math.floor(Math.random() * this.set.size)
let array = Array.from(this.set)
return array[odd]
};
优化
这里用list来优化getRandom函数
这里利用list来存储数据,用map的has来查询是否存在,这里的insert以及remove都是利用了has的特性
在存储的时候,map的key存放是题目给定的值,map的value是当前值在list中的索引
利用好这一点,在插入的时候,需要更新map中的value值,也就是索引
在删除的时候,需要将list值中的最后一个元素放在index处
这里的map以及list就是反向映射
map[value, index]
list[index, value]
var RandomizedSet = function () {
this.map = new Map()
this.list = []
};
/**
* @param {number} val
* @return {boolean}
*/
RandomizedSet.prototype.insert = function (val) {
if (this.map.has(val)) return false
this.map.set(val, this.list.length)
this.list.push(val)
return true
};
/**
* @param {number} val
* @return {boolean}
*/
RandomizedSet.prototype.remove = function (val) {
if (!this.map.has(val)) return false
let index = this.map.get(val)
let lastElement = this.list[this.list.length - 1]
this.list[index] = lastElement
this.map.set(lastElement, index)
this.list.pop()
this.map.delete(val)
return true
};
/**
* @return {number}
*/
RandomizedSet.prototype.getRandom = function () {
let odd = Math.floor(Math.random() * this.list.length)
return this.list[odd]
};