hello 大家好!今天开写一个新章节,每一天一道算法题。让我们一起来学习算法思维吧!
为了实现 RandomizedSet 类,并且保证每个函数的平均时间复杂度为0(1) ,我们可以结合使用数组和哈希表。数组用于存储集合中的元素,哈希表用于记录每个元素在数组中的索引位置。这样在插入、删除和随机获取元素时都能高效地完成操作。
以下是实现代码及详细注释:
class RandomizedSet {constructor() {// 用于存储集合中的元素this.nums = [];// 用于记录每个元素在数组中的索引位置this.valToIndex = new Map();}/*** 向集合中插入元素* @param {number} val - 要插入的元素* @return {boolean} - 如果元素不存在并成功插入返回 true,否则返回 false*/insert(val) {// 检查元素是否已经存在于集合中if (this.valToIndex.has(val)) {return false;}// 将元素添加到数组末尾this.nums.push(val);// 记录元素在数组中的索引this.valToIndex.set(val, this.nums.length - 1);return true;}/*** 从集合中移除元素* @param {number} val - 要移除的元素* @return {boolean} - 如果元素存在并成功移除返回 true,否则返回 false*/remove(val) {// 检查元素是否存在于集合中if (!this.valToIndex.has(val)) {return false;}// 获取要移除元素的索引const index = this.valToIndex.get(val);// 获取数组的最后一个元素const lastVal = this.nums[this.nums.length - 1];// 将最后一个元素移动到要移除元素的位置this.nums[index] = lastVal;// 更新最后一个元素在哈希表中的索引this.valToIndex.set(lastVal, index);// 移除数组的最后一个元素this.nums.pop();// 从哈希表中删除要移除元素的记录this.valToIndex.delete(val);return true;}/*** 随机返回集合中的一个元素* @return {number} - 随机返回的元素*/getRandom() {// 生成一个 0 到数组长度减 1 之间的随机索引const randomIndex = Math.floor(Math.random() * this.nums.length);// 返回该索引对应的元素return this.nums[randomIndex];}
}
代码解释:
构造函数 constructor():
this.nums:一个数组,用于存储集合中的元素。
this.valToIndex:一个 Map 对象,用于记录每个元素在数组中的索引位置,键为元素值,值为该元素在数组中的索引。
插入方法 insert(val):
首先检查 valToIndex 中是否已经存在该元素,如果存在则返回 false。
若不存在,将元素添加到 nums 数组的末尾,并将该元素及其在数组中的索引记录到 valToIndex 中,最后返回 true。
移除方法 remove(val):
先检查 valToIndex 中是否存在该元素,若不存在则返回 false。
若存在,获取该元素在数组中的索引 index,同时获取数组的最后一个元素 lastVal。
将 lastVal 移动到 index 位置,并更新 lastVal 在 valToIndex 中的索引。
移除 nums 数组的最后一个元素,并从 valToIndex 中删除要移除元素的记录,最后返回 true。
随机获取元素方法 getRandom():
使用 Math.random() 生成一个 0 到 1 之间的随机数,乘以数组的长度并向下取整,得到一个随机索引 randomIndex。
返回 nums 数组中 randomIndex 位置的元素。