zoukankan      html  css  js  c++  java
  • [leetcode]380. Insert Delete GetRandom O(1)常数时间插入删除取随机值

    Design a data structure that supports all following operations in average O(1) time.

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

    Solution1:  HashMap + ArrayList

    1. use an ArrayList together with HashMap, making hashmap save key(item)->value(idx) 

    2. To reverse item in O(1), avoiding traversal the whole arrayList in O(n) time, we swap the toDelete item with last item in the list 

    3. Go through an example like this: 

       use HashMap to get removeIdx:

       Set the last item in the list as replaceValue, why the last item? In order to maintain other indices.

       Deal with HashMap: (1) put  (2)delete 

     Deal with List: (1) set  (2)delete

                                                                                          

     code:

     1 class RandomizedSet {
     2     Map<Integer, Integer> map;
     3     List<Integer> list;
     4     Random r; // java 自带类
     5 
     6     /** Initialize your data structure here. */
     7     public RandomizedSet() {
     8         list = new ArrayList<>();
     9         map = new HashMap<>();
    10         r = new Random();    
    11     }
    12     
    13     /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    14     public boolean insert(int val) {
    15         if (map.containsKey(val)) {
    16             return false;
    17         }
    18         map.put(val, list.size());
    19         list.add(val);
    20         return true;
    21     }
    22     
    23     /** Removes a value from the set. Returns true if the set contained the specified element. */
    24     public boolean remove(int val) {
    25         /**
    26         hashmap
    27         30 - 0
    28         40 - 1
    29         50 - 2
    30         60 - 3 
    31         
    32         list: 30 40  50 60 
    33                0   1  2  3
    34         **/
    35         if (!map.containsKey(val))     return false;
    36         int removeIdx = map.get(val);  // Idx: 1
    37         int replaceValue = list.get(list.size()-1); // replaceValue : 60 
    38         
    39         // deal with map
    40         map.put(replaceValue, removeIdx);
    41         map.remove(val);
    42         
    43         // deal with list
    44         list.set(removeIdx, replaceValue); 
    45         list.remove(list.size() -1);
    46       
    47         return true;     
    48     }
    49     
    50     /** Get a random element from the set. */
    51     public int getRandom() {
    52         return list.get(r.nextInt(list.size()));
    53     }
    54 }
  • 相关阅读:
    【MFC】对话框自带滚动条的使用
    【MFC】MFC DLEdit 设计属于自己的编辑框_鼠标悬停
    【MFC】MoveWindow();函数使用详解
    【MFC】SetWindowPos函数使用详解
    模板 key+1
    lazyload 分页加载
    缓慢显示隐藏
    js计算日期的前几天的日期
    判断子元素(or属性)是否存在
    动态加载的数据,hover效果
  • 原文地址:https://www.cnblogs.com/liuliu5151/p/9841061.html
Copyright © 2011-2022 走看看