380. Insert Delete GetRandom O
Posted 会咬人的兔子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了380. Insert Delete GetRandom O相关的知识,希望对你有一定的参考价值。
380. Insert Delete GetRandom O(1)
- Total Accepted: 18668
- Total Submissions: 48402
- Difficulty: Medium
- Contributors: Admin
Design a data structure that supports all following operations in average O(1) time.
insert(val)
: Inserts an item val to the set if not already present.remove(val)
: Removes an item val from the set if present.getRandom
: Returns a random element from current set of elements. Each element must have the same probability of being returned.
Example:
// Init an empty set. RandomizedSet randomSet = new RandomizedSet(); // Inserts 1 to the set. Returns true as 1 was inserted successfully. randomSet.insert(1); // Returns false as 2 does not exist in the set. randomSet.remove(2); // Inserts 2 to the set, returns true. Set now contains [1,2]. randomSet.insert(2); // getRandom should return either 1 or 2 randomly. randomSet.getRandom(); // Removes 1 from the set, returns true. Set now contains [2]. randomSet.remove(1); // 2 was already in the set, so return false. randomSet.insert(2); // Since 2 is the only number in the set, getRandom always return 2. randomSet.getRandom();
Solution:
此题的正确解法是利用到了一个一维数组和一个哈希表,其中数组用来保存数字,哈希表用来建立每个数字和其在数组中的位置之间的映射,对于插入操作,我们先看这个数字是否已经在哈希表中存在,如果存在的话直接返回false,不存在的话,我们将其插入到数组的末尾,然后建立数字和其位置的映射。删除操作是比较tricky的,我们还是要先判断其是否在哈希表里,如果没有,直接返回false。由于哈希表的删除是常数时间的,而数组并不是,为了使数组删除也能常数级,我们实际上将要删除的数字和数组的最后一个数字调换个位置,然后修改对应的哈希表中的值,这样我们只需要删除数组的最后一个元素即可,保证了常数时间内的删除。而返回随机数对于数组来说就很简单了,我们只要随机生成一个位置,返回该位置上的数字即可.
有一些vector的function:.back(), .pop_back()
unordered_map: .count(key) .erase(key)
求random的公式:
return nums[rand() % nums.size()];
1 class RandomizedSet { 2 public: 3 /** Initialize your data structure here. */ 4 RandomizedSet() { 5 6 } 7 8 /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ 9 bool insert(int val) { 10 if(hash.find(val) != hash.end()) return false; 11 //if (hash.count(val)) return false; 12 13 //nums[nums.size()] = val; 14 nums.push_back(val);//vector要用push_back,否则整个container里面是空的 15 hash[val] = nums.size() - 1; 16 return true; 17 } 18 19 /** Removes a value from the set. Returns true if the set contained the specified element. */ 20 bool remove(int val) { 21 //if(hash.find(val) == hash.end()) return false; 22 if(!hash.count(val)) return false; 23 /* 24 int idx = hash[val]; 25 hash.erase(val); 26 //int tmp = nums[idx]; 27 nums[idx] = nums[nums.size() - 1]; 28 //hash相对应也要改 29 hash[nums[nums.size() - 1]] = idx; 30 nums.resize(nums.size() - 1);*/ 31 32 int last = nums.back();//back(): 取vector里最后一个值 33 hash[last] = hash[val];//数字与index的映射:最后一个数字的index改成需删除的数字的index 34 nums[hash[val]] = last;//根据hashmap更改相应index的数值 35 nums.pop_back();//pop_back(): vector里删除最后一个数 36 hash.erase(val);//hashmap里erase(key) 37 38 return true; 39 } 40 41 /** Get a random element from the set. */ 42 int getRandom() { 43 return nums[rand() % nums.size()];//是%百分号啊亲! 44 } 45 private: 46 vector<int> nums; 47 unordered_map<int, int> hash; 48 }; 49 50 /** 51 * Your RandomizedSet object will be instantiated and called as such: 52 * RandomizedSet obj = new RandomizedSet(); 53 * bool param_1 = obj.insert(val); 54 * bool param_2 = obj.remove(val); 55 * int param_3 = obj.getRandom(); 56 */
以上是关于380. Insert Delete GetRandom O的主要内容,如果未能解决你的问题,请参考以下文章
[LeetCode] 380. Insert Delete GetRandom O
380. Insert Delete GetRandom O
LeetCode 380. Insert Delete GetRandom O