题意
设计一个数结构,支持:
insert(x)
: O(1) 插入元素x,如果已经存在返回falseremove(x)
: O(1) 删除元素x,如果x不存在返回falsegetRandom()
: O(1) 的等概率从里面随机返回一个元素
思路
unordered_map
支持
O(1)
插入和删除,只需要
O(1)
的随机返回元素。
我们用一个数组映射一下,用arr[pos] = x
表示位置pos上是元素x。
我们用unordered_map
has来表示hashmap,并且has[x] = pos
代表元素x在数组arr的位置为pos。
于是:
insert(x)
:将元素x插入到unordered_map
的has里面,用has[x] = pos
表示元素x在数组arr的位置在pos上。于是,插入时需要:
- has[x] = pos
- arr[pos] = x
remove(x)
:从has里面找到x的迭代器,并且has[x] = pos
。于是:
- 删除迭代器
- 将arr[pos]上需要删除的那个数和arr最后一个数字交换位置,达到删除的效果。
getRandom()
:返回arr[rand() % n]
代码
const int maxn = 100005;
class RandomizedSet {
private:
int size;
unordered_map<int, int> has;
int arr[maxn];
public:
/** Initialize your data structure here. */
RandomizedSet() {
size = 0;
has.clear();
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
bool insert(int val) {
if (!has.count(val)) {
has[val] = size;
arr[size++] = val;
return true;
}
return false;
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
bool remove(int val) {
auto it = has.find(val);
if (it != has.end()) {
int pos = it->second;
has.erase(it);
swap(arr[pos], arr[--size]);
auto final = has.find(arr[pos]);
if (final != has.end()) final->second = pos;
return true;
}
return false;
}
/** Get a random element from the set. */
int getRandom() {
return arr[rand() % size];
}
};
/**
* 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();
*/