文章目录
C++实现详解
class RandomizedSet {
private:
//用一个hash表以及一个动态数组,每次插入在最后,并通过hash表记录对应的下标
//删除的时候直接与最后的数进行交换,然后pop_back()以达到常数级别的删除
unordered_map<int,int>hash;
vector<int>data;
public:
/** Initialize your data structure here. */
RandomizedSet() {
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
bool insert(int val) {
//如果已经含有该元素返回false
if(hash.count(val))
return false;
data.push_back(val);
hash[val] = data.size()-1;
return true;
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
bool remove(int val) {
//如果data中不存在val就不可能删除成功
if(!hash.count(val))
return false;
//为了得到O(1)时间的复杂度不择手段,用了偷天换日的手法(把要删除位置的值用最后一个位置的值覆盖,然后删除最后一个位置的值即可)
//通过hash表得到它对应的下标,得到后便删除hash中的映射
int pos = hash[val];
//不能在这里erase,因为如果data数组只有一个元素时,一旦pop,后面又会重新创建hash,本来vector中已经没得元素了,但是hash中却又有了映射,所以erase必须在新的hash关系建立之后
int nowVal = data.back();
data[pos] = nowVal;
//删除最后一个数,并且把它的下标映射更新
data.pop_back();
hash[nowVal] = pos;
//最后再删除原来的映射
hash.erase(val);
return true;
}
/** Get a random element from the set. */
int getRandom() {
int size = data.size();
int index = rand()%size;
return data[index];
}
};