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.

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

    常数时间插入、删除和获取随机元素。题意是设计一个数据结构,满足如下操作的平均时间复杂度为O(1)。这个题不难,我先给代码吧。

    Java实现

     1 class RandomizedSet {
     2     HashMap<Integer, Integer> map;
     3     List<Integer> list;
     4     Random rmd;
     5 
     6     /** Initialize your data structure here. */
     7     public RandomizedSet() {
     8         map = new HashMap<>();
     9         list = new ArrayList<>();
    10         rmd = 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         if (!map.containsKey(val)) {
    26             return false;
    27         }
    28         // the index of the removed key
    29         int removedKeyIndex = map.remove(val);
    30         int lastVal = list.remove(list.size() - 1);
    31         if (removedKeyIndex != list.size()) {
    32             list.set(removedKeyIndex, lastVal);
    33             map.put(lastVal, removedKeyIndex);
    34         }
    35         return true;
    36     }
    37 
    38     /** Get a random element from the set. */
    39     public int getRandom() {
    40         return list.get(rmd.nextInt(list.size()));
    41     }
    42 }
    43 
    44 /**
    45  * Your RandomizedSet object will be instantiated and called as such:
    46  * RandomizedSet obj = new RandomizedSet();
    47  * boolean param_1 = obj.insert(val);
    48  * boolean param_2 = obj.remove(val);
    49  * int param_3 = obj.getRandom();
    50  */
    View Code

    既然是要求O(1)的时间复杂度,那么hashmap基本上是不可避免了,因为只有hashmap的读取速度可以达到O(1)。同时再创建一个list,因为得到list size的时间也接近于O(1)。

    insert元素的时候,将val和当前list的size当做key和value加入hashmap;同时将val加入list,注意此时list的size跟加入元素的index的关系,list的size始终比index大1,因为index是从0开始的。

    remove的时候,如果这个元素不在hashmap自然是return false,若存在,则把val从hashmap中移除,同时map.remove()函数也能得到当时这个元素在list中的index。如果这个index不等于当前list的size则说明这个要被移除的元素不是最后一个元素,此时要做的是移除list的最后一个元素,并把他覆盖到被移除元素所在的index上去。这样才能做到list的操作为O(1)。

    跑一个例子吧,比如一开始加了1,2,3,4,5五个数字,他们被加入的时候,hashmap和list应该长类似这样

     1->2->3->4->5

    此时如果删除了数字2,hashmap和list会变成这样,最后一个元素5会被加到list上index为2的地方。

     

    1->5->3->4

    相关题目

    380. Insert Delete GetRandom O(1)

    381. Insert Delete GetRandom O(1) - Duplicates allowed

    LeetCode 题目总结

  • 相关阅读:
    [后缀数组] Luogu P5028 Annihilate
    [后缀数组] Luogu P3809 后缀排序
    [差分][线段树] Luogu P4243 等差数列
    [线段树] Luogu P4314 COU监控
    [二分][dp凸优化] Luogu P4383 林克卡特树lct
    [树上差分][dfs] Luogu P4652 One-Way Streets
    [dfs][思维] Luogu P3208 矩阵
    [dfs][二进制状压] Luogu P4906 小奔关闹钟
    [容斥] Luogu P5339 唱、跳、rap和篮球
    [dfs][模拟网络流] Luogu P4189 星际旅行
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12765048.html
Copyright © 2011-2022 走看看