题目地址:
https://leetcode.com/problems/insert-delete-getrandom-o1/
要求实现一个数据结构,可以在
O
(
1
)
O(1)
O(1)时间内:
1、添加一个数;添加成功则返回true,否则如果已经有了返回false;
2、删除一个数;删除成功则返回true,否则如果没有则返回false;
3、随机取出一个数,但每个数取到的概率要均等。
由于要实现删除一个数也要达到 O ( 1 ) O(1) O(1),所以我们想到用一个HashMap记录每个数值出现的位置,删除的时候可以先把那个数字和list末尾数交换,然后删除就是 O ( 1 ) O(1) O(1)的了。但要注意对哈希表也做相应的更改。代码如下:
class RandomizedSet {
public:
vector<int> v;
unordered_map<int, int> mp;
RandomizedSet() {}
bool insert(int x) {
if (mp.count(x)) return false;
v.push_back(x);
mp[x] = v.size() - 1;
return true;
}
bool remove(int x) {
if (!mp.count(x)) return false;
// 否则取出其下标,与最后一个数字交换
int idx = mp[x];
swap(v[idx], v.back());
// 换完了更新那个被换到idx的数字的位置
mp[v[idx]] = idx;
// 删除掉末尾,map里也把x删除掉
v.pop_back();
mp.erase(x);
return true;
}
int getRandom() { return v[rand() % v.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();
*/
所有操作时间复杂度 O ( 1 ) O(1) O(1),空间 O ( n ) O(n) O(n)。