题目
380.O(1) 时间插入、删除和获取随机元素
题目大意
实现RandomizedSet
类:
RandomizedSet()
初始化RandomizedSet
对象bool insert(int val)
当元素val
不存在时,向集合中插入该项,并返回true
;否则,返回false
。bool remove(int val)
当元素val
存在时,从集合中移除该项,并返回true
;否则,返回false
。int getRandom()
随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。
你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1)
。
样例
示例:
输入
["RandomizedSet", "insert", "remove", "insert", "getRandom", "remove", "insert", "getRandom"]
[[], [1], [2], [2], [], [1], [2], []]
输出
[null, true, false, true, 2, true, false, 2]
解释
RandomizedSet randomizedSet = new RandomizedSet();
randomizedSet.insert(1); // 向集合中插入 1 。返回 true 表示 1 被成功地插入。
randomizedSet.remove(2); // 返回 false ,表示集合中不存在 2 。
randomizedSet.insert(2); // 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
randomizedSet.getRandom(); // getRandom 应随机返回 1 或 2 。
randomizedSet.remove(1); // 从集合中移除 1 ,返回 true 。集合现在包含 [2] 。
randomizedSet.insert(2); // 2 已在集合中,所以返回 false 。
randomizedSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom 总是返回 2 。
数据规模
提示:
- − 2 31 < = v a l < = 2 31 − 1 -2^{31} <= val <= 2^{31} - 1 −231<=val<=231−1
- 最多调用
insert
、remove
和getRandom
函数 2 × 1 0 5 2 \times 10^5 2×105 次 - 在调用
getRandom
方法时,数据结构中 至少存在一个 元素。
思路
考虑使用unordered_map
对元素进行记录,由于需要满足每个函数的 平均 时间复杂度为
O
(
1
)
O(1)
O(1),所以很容易想到使用基于哈希表原理的unordered_map
,然后用数组vector<int>a
来存储数字。
- 对于函数
RandomizedSet()
:直接情况mp
和a
。 - 对于函数
bool insert(int val)
:先判断mp[val]
是否存在,如果存在直接返回false
,否则a.push_back(val)
,同时mp[val]=a.size()
- 对于函数
bool remove(int val)
:先判断mp[val]
是否存在,如果不存在直接返回false
,否则将a
中最后一个元素放到a[mp[val]-1
的位置上,同时更新mp
对两者位置的记录。 - 对于函数
int getRandom()
:直接随机输出即可。
代码
// short int long float double bool char string void
// array vector stack queue auto const operator
// class public private static friend extern
// sizeof new delete return cout cin memset malloc
// relloc size length memset malloc relloc size length
// for while if else switch case continue break system
// endl reverse sort swap substr begin end iterator
// namespace include define NULL nullptr exit equals
// index col row arr err left right ans res vec que sta
// state flag ch str max min default charray std
// maxn minn INT_MAX INT_MIN push_back insert
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int>PII;
typedef pair<int, string>PIS;
const int maxn=1e6+50;//注意修改大小
long long read(){long long x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;}
ll qpow(ll x,ll q,ll Mod){ll ans=1;while(q){if(q&1)ans=ans*x%Mod;q>>=1;x=(x*x)%Mod;}return ans%Mod;}
class RandomizedSet {
public:
unordered_map<int,int>mp;
vector<int>a;
RandomizedSet() {
mp.clear();
a.clear();
}
bool insert(int val) {
if(mp[val])return 0;
a.push_back(val);
mp[val]=a.size();
return 1;
}
bool remove(int val) {
if(!mp[val])return 0;
a[mp[val]-1]=a[a.size()-1];
mp[a[a.size()-1]]=mp[val];
a.pop_back();
mp[val]=0;
return 1;
}
int getRandom() {
int t=rand()%a.size();
return a[t];
}
};
/**
* 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();
*/