分析
看见插入和删除都要 ,很自然想到利用可变长数组进行操作。 但这样就引入了一个问题:变长数组中,获取单个元素通常都要求数组有序, 且绝大部分时间复杂度都大于 。 因此我们需要其他方法来实现。
注意到题目中并没有限制空间复杂度。 因此我们可以通过引入哈希表,用哈希表记录数组下标。 通过哈希表来判断元素是否存在,即可完美实现 的要求。 删除操作中,由于直接删除会涉及到后续元素的前移, 所以我们可以交换目标元素与数组最后一个元素的位置。 从而在常数时间里移除元素。
解答
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)]; }};