zoukankan      html  css  js  c++  java
  • 380. Insert Delete GetRandom O(1)

    问题:

    设计数据结构,使得以下三个方法的时间复杂度都为O(1)

    1. insert(val): Inserts an item val to the set if not already present.
    2. remove(val): Removes an item val from the set if present.
    3. 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();
    

      

    解法:

    本题需让insert,remove的复杂度为O(1)

    数组的insert方法复杂度满足,remove中的查找不满足,因此加入hash来帮助记录消化查找的代价。

    vector<int> nums

    unordered_map<int, int>  //(key: nums[i], value: i)

    代码参考:

     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(mapnums.find(val)!=mapnums.end()){
    11             return false;
    12         }
    13         nums.push_back(val);
    14         mapnums[val]=nums.size()-1;
    15         return true;
    16     }
    17     
    18     /** Removes a value from the set. Returns true if the set contained the specified element. */
    19     bool remove(int val) {
    20         if(mapnums.find(val)==mapnums.end()){
    21             return false;
    22         }
    23         int last=nums.back();
    24         nums[mapnums[val]]=last;
    25         mapnums[last]=mapnums[val];
    26         nums.pop_back();
    27         mapnums.erase(val);
    28         return true;
    29     }
    30     
    31     /** Get a random element from the set. */
    32     int getRandom() {
    33         return nums[rand() % nums.size()];
    34     }
    35     
    36 private:
    37     vector<int> nums;
    38     unordered_map<int, int> mapnums;
    39 };
    40 
    41 /**
    42  * Your RandomizedSet object will be instantiated and called as such:
    43  * RandomizedSet* obj = new RandomizedSet();
    44  * bool param_1 = obj->insert(val);
    45  * bool param_2 = obj->remove(val);
    46  * int param_3 = obj->getRandom();
    47  */
  • 相关阅读:
    Java锁---偏向锁、轻量级锁、自旋锁、重量级锁
    Java自旋锁
    设计模式的原则
    CGLIB介绍与原理(通过继承的动态代理)
    Android Messenger
    Android AIDL的用法
    长连接和短连接和推送
    Java对称加密算法
    Android 热修复技术中的CLASS_ISPREVERIFIED问题
    Java类加载器
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/12697445.html
Copyright © 2011-2022 走看看