一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
LeetCode每日一题打卡专栏正式启动!不出意外将日更LeetCode的每日一题,敬请期待。
个人博客链接:bbstudy.net/ (等毕业论文做好后续会完善相关功能)
4.13:O(1) 时间插入、删除和获取随机元素
LeetCode 380,点击题目可直接跳转至LeetCode
题解:哈希表
对于获取随机元素,数组可以在O(1)时间做到,但是对于插入和删除操作,数组却无能为力。
对于插入和删除操作,哈希表可以在O(1)时间做到,但是对于获取随机元素操作,哈希表却又不可奈何。
于是思考:能否将两者结合,实现O(1)时间:插入、删除和获取随机元素。
- 用一可变数组num:存储集合中的元素
- 哈希表中:key存储num中的元素,value存储对应的索引
当执行插入操作(插入元素在集合中未出现)时:
- num数组直接在末尾添加
- 哈希表则把插入的元素和对应的末尾下标存入其中
当执行删除操作(待删除元素在集合中)时:
- 将num数组中末尾元素移动至当前需要删除元素的索引处
- 在哈希表中更新num数组中末尾对应的value值(即索引)
- num数组删除最后一个元素,哈希表删除待删除的元素
借此巩固下Java集合类的使用,于是提供C++和Java代码:
C++代码:
class RandomizedSet {
public:
unordered_map<int,int> mp; //key->num,value->index
vector<int> num;
RandomizedSet() {
mp.clear();num.clear();
srand(time(0)); //随机数种子
}
bool insert(int val) {
if(mp.count(val)) return false;
num.push_back(val);
mp[val]=num.size()-1;
return true;
}
bool remove(int val) {
if(!mp.count(val)) return false;
//将num数组中最后一个元素填入到此位置
int index=mp[val];
int x=num.back();
mp[x]=index;
num[index]=x;
//在num数组中删除最后一个元素,同时mp中也删除需要删除的元素
num.pop_back();mp.erase(val);
return true;
}
int getRandom() {
int pos=rand()%num.size();
return num[pos];
}
};
/**
* 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();
*/
Java代码:
class RandomizedSet {
Map<Integer,Integer> map;
List<Integer> num;
public RandomizedSet() {
map=new HashMap<Integer,Integer>();
num=new ArrayList<>();
}
public boolean insert(int val) {
if(map.containsKey(val)) return false;
num.add(val);
map.put(val,num.size()-1);
return true;
}
public boolean remove(int val) {
if(!map.containsKey(val)) return false;
//将num最后一个元素移动至当前位置
int index=map.get(val);
int last=num.get(num.size()-1);
num.set(index,last);
map.put(last,index);
//删除num最后一个元素,删除map中需要删除的元素
num.remove(num.size()-1);
map.remove(val);
return true;
}
public int getRandom() {
Random rand=new Random();
int index=rand.nextInt(num.size());
return num.get(index);
}
}