o-1-时间插入、删除和获取随机元素
题目
实现 `RandomizedSet`` 类:
RandomizedSet()
初始化RandomizedSet
对象bool insert(int val)
当元素val
不存在时, 向集合中插入该项, 并返回true
; 否则, 返回false
.bool remove(int val)
当元素val
存在时, 从集合中移除该项, 并返回true
; 否则, 返回false
.int getRandom()
随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素). 每个元素应该有相同的概率返回.
要求以上三个方法都是 O(1) 时间复杂度.
题解
对于 insert 和 remove 操作容易想到使用哈希表来实现 O(1) 复杂度, 但对于 getRandom 操作, 比较理想的情况是能够在一个数组内随机下标进行返回.
- JavaScript
- Rust
var RandomizedSet = function () {
// 维护一个 map, key 是 val, value 为 idx
this.map = new Map()
// 将数据存储到一个数组, 便于随机获取.
this.nums = []
}
/**
* @param {number} val
* @return {boolean}
*/
RandomizedSet.prototype.insert = function (val) {
if (this.map.has(val)) return false
this.map.set(val, this.nums.length)
this.nums.push(val)
return true
}
/**
* @param {number} val
* @return {boolean}
*/
RandomizedSet.prototype.remove = function (val) {
if (!this.map.has(val)) return false
const idx = this.map.get(val)
// 将数组的最后一个元素复写到 idx 的位置, 这样保证在数组中把 val 删除掉了
this.nums[idx] = this.nums[this.nums.length - 1]
// 此时数组最后一个元素没用了, pop 掉
this.nums.pop()
// 在 map 中将 val 移除
this.map.delete(val)
// 由于最后一个元素改变了位置(this.nums.length - 1 -> idx), 需要更新最后一个元素在 map 中的 value
this.map.set(this.nums[idx], idx)
return true
}
/**
* @return {number}
*/
RandomizedSet.prototype.getRandom = function () {
const randomIdx = Math.floor(Math.random() * this.nums.length)
return this.nums[randomIdx]
}
/**
* Your RandomizedSet object will be instantiated and called as such:
* var obj = new RandomizedSet()
* var param_1 = obj.insert(val)
* var param_2 = obj.remove(val)
* var param_3 = obj.getRandom()
*/
use rand::Rng;
use std::collections::HashMap;
#[derive(Debug)]
struct RandomizedSet {
map: HashMap<i32, usize>,
nums: Vec<i32>,
}
/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl RandomizedSet {
/** Initialize your nums structure here. */
fn new() -> Self {
RandomizedSet {
map: HashMap::new(),
nums: Vec::new(),
}
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
fn insert(&mut self, val: i32) -> bool {
if self.map.contains_key(&val) {
return false;
}
self.map.insert(val, self.nums.len());
self.nums.push(val);
true
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
fn remove(&mut self, val: i32) -> bool {
if !self.map.contains_key(&val) {
return false;
}
let idx = self.map.remove(&val).unwrap();
let last = self.nums.pop().unwrap();
if idx != self.nums.len() {
self.nums[idx] = last;
self.map.insert(last, idx);
}
true
}
/** Get a random element from the set. */
fn get_random(&self) -> i32 {
self.nums[rand::thread_rng().gen_range(0..self.nums.len())]
}
}
/**
* Your RandomizedSet object will be instantiated and called as such:
* let obj = RandomizedSet::new();
* let ret_1: bool = obj.insert(val);
* let ret_2: bool = obj.remove(val);
* let ret_3: i32 = obj.get_random();
*/