链接:381. O(1) 时间插入、删除和获取随机元素 - 允许重复
题解:
class RandomizedCollection {
private:
std::unordered_map<int, std::unordered_set<int>> tabel_;
std::vector<int> nums_;
public:
/** Initialize your data structure here. */
RandomizedCollection() {
tabel_.clear();
nums_.clear();
}
/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
bool insert(int val) {
bool ret = tabel_.find(val) == tabel_.end();
nums_.push_back(val);
tabel_[val].insert(nums_.size()-1);
return ret;
}
/** Removes a value from the collection. Returns true if the collection contained the specified element. */
bool remove(int val) {
// 判断val是否存储
if(tabel_.find(val) == tabel_.end()) {
return false;
}
// 找到val存在的下标
int index = *(tabel_[val].begin());
// 将数组中最后元素替换index位置
nums_[index] = nums_.back();
// 将index从table中删除
tabel_[val].erase(index);
// 将nums_.back()元素的下标也删除
tabel_[nums_.back()].erase(nums_.size()-1);
// 更新nums_.back()的下标
if(index < nums_.size()-1) {
tabel_[nums_.back()].insert(index);
}
// 如果index的table全部删除了,删除将val从table
if(tabel_[val].size() == 0) {
tabel_.erase(val);
}
nums_.pop_back();
return true;
}
/** Get a random element from the collection. */
int getRandom() {
return nums_[random()%nums_.size()];
}
};
/**
* * Your RandomizedCollection object will be instantiated and called as such:
* * RandomizedCollection* obj = new RandomizedCollection();
* * bool param_1 = obj->insert(val);
* * bool param_2 = obj->remove(val);
* * int param_3 = obj->getRandom();
* */