381. Insert Delete GetRandom O(1) - Duplicates allowed
2017-03-04 19:49
471 查看
Insert Delete GetRandom O1 - Duplicates allowed
题目描述
代码实现
Note: Duplicate elements are allowed.
insert(val): Inserts an item val to the collection.
remove(val): Removes an item val from the collection if present.
getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.
Example:
就是弄一个数据结构,使得其可以插入数据、删除数据、返回随机数据。
但是它的时间复杂度只能是O(1)
但是这种方法在返回随机数的时候复杂度是O(n),所以这里需要做一些修改。
这里有一种更好的方法,就是使用vector和map进行。使用vector方便搜索,使用map比较容易进行存储索引及值的映射。插入和搜索比较简单,问题是删除会巧妙一点。这里的话,使用的是删除某个元素,那么就把该元素的映射的索引都找到,找到索引最大的那个,把它和vector存储的最外面的元素做一个交换,那么就只需要修改最外面元素的索引,就能把需要的数字删除。
在leetcode1我看到了有人使用multimap,算法效率和上面我写的一样:
题目描述
代码实现
381. Insert Delete GetRandom O(1) - Duplicates allowed
题目描述
Design a data structure that supports all following operations in average O(1) time.Note: Duplicate elements are allowed.
insert(val): Inserts an item val to the collection.
remove(val): Removes an item val from the collection if present.
getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.
Example:
// Init an empty collection. RandomizedCollection collection = new RandomizedCollection(); // Inserts 1 to the collection. Returns true as the collection did not contain 1. collection.insert(1); // Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1]. collection.insert(1); // Inserts 2 to the collection, returns true. Collection now contains [1,1,2]. collection.insert(2); // getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3. collection.getRandom(); // Removes 1 from the collection, returns true. Collection now contains [1,2]. collection.remove(1); // getRandom should return 1 and 2 both equally likely. collection.getRandom();
就是弄一个数据结构,使得其可以插入数据、删除数据、返回随机数据。
但是它的时间复杂度只能是O(1)
代码实现
这里我先实现了一种使用map和一个整数记录了其大小。class RandomizedCollection { map<int, int> hash; int size; public: RandomizedCollection() { size = 0; } bool insert(int val) { hash[val]++; size++; return (hash[val] == 1); } bool remove(int val) { if(hash.count(val) == 0) return false; if(--hash[val] == 0) hash.erase(val); size--; return true; } int getRandom() { int ind = rand() % size + 1; map<int, int>::iterator it; for(it = hash.begin(); it != hash.end(); it++) { if(ind <= it->second) return it->first; else ind -= it->second; } return it->first; } }; /** * Your RandomizedCollection object will be instantiated and called as such: * RandomizedCollection obj = new RandomizedCollection(); * bool param_1 = obj.insert(val); * bool param_2 = obj.remove(val); * int param_3 = obj.getRandom(); */
但是这种方法在返回随机数的时候复杂度是O(n),所以这里需要做一些修改。
这里有一种更好的方法,就是使用vector和map进行。使用vector方便搜索,使用map比较容易进行存储索引及值的映射。插入和搜索比较简单,问题是删除会巧妙一点。这里的话,使用的是删除某个元素,那么就把该元素的映射的索引都找到,找到索引最大的那个,把它和vector存储的最外面的元素做一个交换,那么就只需要修改最外面元素的索引,就能把需要的数字删除。
class RandomizedCollection { map<int, vector<int> > hash; vector<int> res; public: RandomizedCollection() { } bool insert(int val) { hash[val].push_back(res.size()); res.push_back(val); return (hash[val].size() == 1); } bool remove(int val) { if(!hash.count(val)) return false; int tp = hash[val].back(); hash[val].pop_back(); if(!hash[val].size()) hash.erase(val); if(res.size() != tp + 1) { res[tp] = res[res.size()-1]; hash[res[tp]].pop_back(); hash[res[tp]].insert(hash[res[tp]].begin(), tp); } res.pop_back(); return true; } int getRandom() { int sz = res.size(); if(!sz) return 1; int ind = rand() % sz; return res[ind]; } }; /** * Your RandomizedCollection object will be instantiated and called as such: * RandomizedCollection obj = new RandomizedCollection(); * bool param_1 = obj.insert(val); * bool param_2 = obj.remove(val); * int param_3 = obj.getRandom(); */
在leetcode1我看到了有人使用multimap,算法效率和上面我写的一样:
class RandomizedCollection { private: std::vector<int> nums; std::unordered_multimap<int, int> pcmap; public: /** Initialize your data structure here. */ RandomizedCollection() { } /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ bool insert(int val) { nums.push_back(val); int count = pcmap.count(val); pcmap.insert(std::make_pair(val, nums.size() - 1)); return count == 0; } /** Removes a value from the collection. Returns true if the collection contained the specified element. */ bool remove(int val) { auto iter = pcmap.find(val); if (iter == pcmap.end()) return false; int pos = iter->second; pcmap.erase(iter, std::next(iter)); int lastVal = nums.back(); nums[pos] = lastVal; // Special case in consideration: remove the last inserted value (count: 0->1) for (auto iterLast = pcmap.find(lastVal); iterLast != pcmap.end(); iterLast++) { if (iterLast->second == nums.size() - 1) { pcmap.erase(iterLast, std::next(iterLast)); pcmap.insert(std::make_pair(lastVal, pos)); break; // break early to avoid meaningless loops } } nums.pop_back(); // pop last return true; } /** Get a random element from the collection. */ int getRandom() { int pos = rand() % nums.size(); return nums[pos]; } }; /** * Your RandomizedCollection object will be instantiated and called as such: * RandomizedCollection obj = new RandomizedCollection(); * bool param_1 = obj.insert(val); * bool param_2 = obj.remove(val); * int param_3 = obj.getRandom(); */
相关文章推荐
- 381. Insert Delete GetRandom O(1) - Duplicates allowed
- 381. Insert Delete GetRandom O(1) - Duplicates allowed
- 381. Insert Delete GetRandom O(1) - Duplicates allowed
- 381. Insert Delete GetRandom O(1) - Duplicates allowed
- 381. Insert Delete GetRandom O(1) - Duplicates allowed
- 381. Insert Delete GetRandom O(1) - Duplicates allowed
- Insert Delete GetRandom O(1) - Duplicates allowed
- Insert Delete GetRandom O(1) - Duplicates allowed
- leetcode之Insert Delete GetRandom O(1) - Duplicates allowed
- [LeetCode] Insert Delete GetRandom O(1) - Duplicates allowed
- LeetCode-Insert Delete GetRandom O(1) - Duplicates allowed
- Leetcode: Insert Delete GetRandom O(1) - Duplicates allowed
- Insert Delete GetRandom O(1) - Duplicates allowed 解法
- Leetcode Insert Delete GetRandom O(1) Duplicates allowed and Not allowed
- [LeetCode] Insert Delete GetRandom O(1) - Duplicates allowed 常数时间内插入删除和获得随机数 - 允许重复
- LeetCode Insert Delete GetRandom O(1) - Duplicates allowed
- LeetCode 381---Insert Delete GetRandom O(1) - Duplicates allowed
- LeetCode Insert Delete GetRandom O(1) - Duplicates allowed
- 【Leetcode】Insert Delete GetRandom O(1) - Duplicates allowed
- Insert Delete GetRandom O(1) - Duplicates allowed in JAVA