# O(1) 时间插入、删除和获取随机元素 - 允许重复
设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构。
注意: 允许出现重复元素。
insert(val)
:向集合中插入元素 val。
remove(val)
:当 val 存在时,从集合中移除一个 val。
getRandom
:从现有集合中随机获取一个元素。每个元素被返回的概率应该与其在集合中的数量呈线性相关。
示例:
// 初始化一个空的集合。
RandomizedCollection collection = new RandomizedCollection();
// 向集合中插入 1 。返回 true 表示集合不包含 1 。
collection.insert(1);
// 向集合中插入另一个 1 。返回 false 表示集合包含 1 。集合现在包含 [1,1] 。
collection.insert(1);
// 向集合中插入 2 ,返回 true 。集合现在包含 [1,1,2] 。
collection.insert(2);
// getRandom 应当有 2/3 的概率返回 1 ,1/3 的概率返回 2 。
collection.getRandom();
// 从集合中删除 1 ,返回 true 。集合现在包含 [1,2] 。
collection.remove(1);
// getRandom 应有相同概率返回 1 和 2 。
collection.getRandom();
以下错误的选项是?
## aop
### before
```cpp
#include
using namespace std;
```
### after
```cpp
```
## 答案
```cpp
class RandomizedCollection
{
public:
/** Initialize your data structure here. */
RandomizedCollection()
{
this->num = 0;
}
/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
bool insert(int val)
{
this->num++;
bool res;
if (this->M.find(val) == this->M.end() || this->M[val] == 0)
{
this->M[val] = 1;
res = true;
}
else
{
this->M[val]++;
res = false;
}
return res;
}
/** Removes a value from the collection. Returns true if the collection contained the specified element. */
bool remove(int val)
{
if (this->M.find(val) == this->M.end() || this->M[val] == 0)
{
return false;
}
else
{
M[val]--;
this->num--;
return true;
}
}
/** Get a random element from the collection. */
int getRandom()
{
if (this->num > 0)
{
srand((unsigned)time(NULL));
int randomValue = rand() % (this->num) + 1;
for (auto it : M)
{
randomValue -= it.second;
if (randomValue <= 0)
return it.first;
}
}
return 0;
}
private:
unordered_map M;
int num;
};
```
## 选项
### A
```cpp
class RandomizedSet
{
public:
vector nums;
unordered_map numIndex;
int size;
/** Initialize your data structure here. */
RandomizedSet()
{
size = 0;
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
bool insert(int val)
{
if (numIndex.count(val) == 1)
return false;
nums.push_back(val);
numIndex[val] = size;
size++;
return true;
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
bool remove(int val)
{
if (numIndex.count(val) == 0)
return false;
int last = nums.back();
nums[numIndex[val]] = last;
numIndex[last] = numIndex[val];
nums.pop_back();
numIndex.erase(val);
size--;
return true;
}
/** Get a random element from the set. */
int getRandom()
{
return nums[random() % size];
}
};
```
### B
```cpp
class RandomizedCollection
{
public:
unordered_map> idx;
vector nums;
/** Initialize your data structure here. */
RandomizedCollection()
{
}
/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
bool insert(int val)
{
nums.push_back(val);
idx[val].insert(nums.size() - 1);
return idx[val].size() == 1;
}
/** Removes a value from the collection. Returns true if the collection contained the specified element. */
bool remove(int val)
{
if (idx.find(val) == idx.end())
{
return false;
}
int i = *(idx[val].begin());
nums[i] = nums.back();
idx[val].erase(i);
idx[nums[i]].erase(nums.size() - 1);
if (i < nums.size() - 1)
{
idx[nums[i]].insert(i);
}
if (idx[val].size() == 0)
{
idx.erase(val);
}
nums.pop_back();
return true;
}
/** Get a random element from the collection. */
int getRandom()
{
return nums[rand() % nums.size()];
}
};
```
### C
```cpp
class RandomizedCollection
{
public:
vector nums;
unordered_map> numsIndex;
int size;
/** Initialize your data structure here. */
RandomizedCollection()
{
size = 0;
}
/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
bool insert(int val)
{
nums.push_back(val);
numsIndex[val].insert(size);
size++;
return numsIndex[val].size() == 1;
}
/** Removes a value from the collection. Returns true if the collection contained the specified element. */
bool remove(int val)
{
if (numsIndex.count(val) == 0)
return false;
int last = nums.back();
int id = size - 1;
if (last != val)
{
id = *(numsIndex[val].begin());
numsIndex[last].erase(size - 1);
numsIndex[last].insert(id);
nums[id] = last;
}
nums.pop_back();
size--;
numsIndex[val].erase(id);
if (numsIndex[val].empty())
numsIndex.erase(val);
return true;
}
/** Get a random element from the collection. */
int getRandom()
{
return nums[random() % size];
}
};
```