leetcode 380. Insert Delete GetRandom O(1)

末蓝、 2022-06-07 02:50 238阅读 0赞

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();

直接看代码吧。

代码如下:

  1. /*
  2. * 使用Map保存元素和对应的index,这道题要注意,不允许重复元素
  3. */
  4. public class RandomizedSet
  5. {
  6. Map<Integer,Integer> map;
  7. List<Integer> list;
  8. int size;
  9. /** Initialize your data structure here. */
  10. public RandomizedSet()
  11. {
  12. map = new HashMap<Integer,Integer>();
  13. list = new ArrayList<Integer>();
  14. this.size = 0;
  15. }
  16. /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
  17. public boolean insert(int val)
  18. {
  19. if(map.containsKey(val))
  20. return false;
  21. else
  22. {
  23. list.add(size,val);
  24. map.put(val,size++);
  25. return true;
  26. }
  27. }
  28. /** Removes a value from the set. Returns true if the set contained the specified element. */
  29. public boolean remove(int val)
  30. {
  31. if(!map.containsKey(val))
  32. return false;
  33. else if(size == 0)
  34. map.remove(val);
  35. else
  36. {
  37. int tailKey = list.get(size-1);
  38. map.put(tailKey,map.get(val));
  39. list.set(map.get(val),tailKey);
  40. size--;
  41. map.remove(val);
  42. }
  43. return true;
  44. }
  45. /** Get a random element from the set. */
  46. public int getRandom()
  47. {
  48. Random rdm = new Random();
  49. return list.get(rdm.nextInt(size));
  50. }
  51. }

下面是C++的做法

这道题让我们在常数时间范围内实现插入删除和获得随机数操作,如果这道题没有常数时间的限制,那么将会是一道非常简单的题,我们直接用一个set就可以搞定所有的操作。但是由于时间的限制,我们无法在常数时间内实现获取随机数,所以只能另辟蹊径。此题的正确解法是利用到了一个一维数组和一个哈希表,其中数组用来保存数字,哈希表用来建立每个数字和其在数组中的位置之间的映射,对于插入操作,我们先看这个数字是否已经在哈希表中存在,如果存在的话直接返回false,不存在的话,我们将其插入到数组的末尾,然后建立数字和其位置的映射。删除操作是比较tricky的,我们还是要先判断其是否在哈希表里,如果没有,直接返回false。由于哈希表的删除是常数时间的,而数组并不是,为了使数组删除也能常数级,我们实际上将要删除的数字和数组的最后一个数字调换个位置,然后修改对应的哈希表中的值,这样我们只需要删除数组的最后一个元素即可,保证了常数时间内的删除。而返回随机数对于数组来说就很简单了,我们只要随机生成一个位置,返回该位置上的数字即可,参见代码如下:

代码如下:

  1. #include <iostream>
  2. #include <vector>
  3. #include <map>
  4. #include <unordered_map>
  5. #include <set>
  6. #include <unordered_set>
  7. #include <queue>
  8. #include <stack>
  9. #include <string>
  10. #include <climits>
  11. #include <algorithm>
  12. #include <sstream>
  13. #include <functional>
  14. #include <bitset>
  15. #include <numeric>
  16. #include <cmath>
  17. #include <regex>
  18. using namespace std;
  19. class RandomizedSet
  20. {
  21. public:
  22. vector<int> nums;
  23. unordered_map<int, int> m;
  24. /** Initialize your data structure here. */
  25. RandomizedSet()
  26. {
  27. }
  28. /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
  29. bool insert(int val)
  30. {
  31. if (m.count(val))
  32. return false;
  33. nums.push_back(val);
  34. m[val] = nums.size() - 1;
  35. return true;
  36. }
  37. /** Removes a value from the set. Returns true if the set contained the specified element. */
  38. bool remove(int val)
  39. {
  40. if (!m.count(val))
  41. return false;
  42. int last = nums.back();
  43. m[last] = m[val];
  44. nums[m[val]] = last;
  45. nums.pop_back();
  46. m.erase(val);
  47. return true;
  48. }
  49. /** Get a random element from the set. */
  50. int getRandom()
  51. {
  52. return nums[rand() % nums.size()];
  53. }
  54. };

发表评论

表情:
评论列表 (有 0 条评论,238人围观)

还没有评论,来说两句吧...

相关阅读