O(1) 时间插入、删除和获取随机元素
分析
看见插入和删除都要求 ,很自然会先想到使用数组。 不过,仅靠数组虽然可以做到按下标随机访问为 , 但删除任意元素通常需要移动后续元素,因此难以保证删除操作也是 。 因此我们需要引入额外的数据结构来配合实现。
注意到题目中并没有限制空间复杂度。 因此我们可以通过引入哈希表,用哈希表记录数组下标。 通过哈希表判断元素是否存在并记录其下标,就可以配合数组满足题目的时间复杂度要求。 删除操作中,由于直接删除会涉及到后续元素的前移, 所以我们可以交换目标元素与数组最后一个元素的位置。 从而在常数时间里移除元素。
解答
class RandomizedSet {private: vector<int> nums; unordered_map<int, int> indices; mt19937 rng; uniform_int_distribution<int> dist;
public: RandomizedSet() {}
bool insert(int val) { if (indices.count(val)) return false;
auto index = nums.size(); nums.emplace_back(val); indices[val] = index;
return true; }
bool remove(int val) { if (!indices.count(val)) return false;
auto index = indices[val]; auto last = nums.back(); nums[index] = last; indices[last] = index; nums.pop_back(); indices.erase(val);
return true; }
int getRandom() { uniform_int_distribution<int>::param_type parm(0, nums.size() - 1);
return nums[dist(rng, parm)]; }};