哈希加数组,哈希的键就是这个元素的值,哈希的值是这个元素在数组中的下标。要remove的话,就把这个元素换到数组尾部然后erase,这样就不会有移动元素的时间复杂度,map也有erase的函数,参数就是键很方便。
坑点:remove交换位置后,要将最后一个元素换到前面去了,所以最后一个元素对应的下标需要在map中更新
class RandomizedSet {
public:
//所有时间复杂度均在O(1),插入删除要在O(1)肯定是链表了吧?
//vector的push_back也可以,但是vector的查找不行,链表的查找也不行
//考虑用哈希数组,哈希表直接用key存数字,value存对应结点在数组中的下标
//将要删除的元素和最后一个元素交换,这样就可以实现不移动其他元素删除了O(1)
/** 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) {
if(ma.count(val) == 0){
vec.push_back(val);
ma[val] = vec.size()-1;
return true;
}
else{
return false;
}
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
bool remove(int val) {
if(ma.count(val) != 0){
int tmp = vec[vec.size()-1];
swap(vec[ma[val]],vec[vec.size()-1]);
//交换后要更新ma中的下标,此时ma[val]记录的下标对应的是最后一个数字的
ma[tmp] = ma[val];
vec.erase(vec.end()-1);
ma.erase(val);
return true;
}
else{
return false;
}
}
/** Get a random element from the set. */
int getRandom() {
int r = rand()%(vec.size());
return vec[r];
}
private:
unordered_map<int,int> ma;
vector<int> vec;
};
/**
* Your RandomizedSet object will be instantiated and called as such:
* RandomizedSet* obj = new RandomizedSet();
* bool param_1 = obj->insert(val);
* bool param_2 = obj->remove(val);
* int param_3 = obj->getRandom();
*/