• [leetcode]380. Insert Delete GetRandom O(1)设计数据结构,实现存,删,随机取的时间复杂度为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();
    思路:肯定是借助java已有的数据结构进行设计,常用的有ArrayList,HashMap,HashSet,能做到随机取数的有前两个,能实现判断和删除O(1)是否包含的是后两个,
    而且map想判断的话,数据必须存key,这样就不能取数了。用list取数的时候,必须要知道数据和下标的对应关系,所以可以map和list配合
     1 * 没有一个现成的数据结构可以符合要求,但是可以组合使用它们实现,list存数据,map的key存数据,value存数据在list中的下标,
     2 * 这样ArrayList可以实现存O(1),删除借助map获取下标,实现O(1),判断重复用map的containsKey方法
     3 * 其实insert和remove,map都可以单独实现O(1),不单独用map就是因为无法实现getRandom,因为由于判断重复需要containsKey方法,所以数据必须存key而不是value
     4 * 但是随机取数时,map无法取出指定key,所以不能单独用map,随机取数只能用list,随机指定下标而取出数值
     5 * getRandom要求知道数据结构的大小,并且存储元素是相邻的
     6 public static void main(String[] args) {
     7         Q380InsertDeleteGetRandomO1 q = new Q380InsertDeleteGetRandomO1();
     8         q.set.insert(0);
     9         q.set.insert(1);
    10         q.set.remove(0);
    11         System.out.println(q.set.list);
    12         System.out.println(q.set.map);
    13         System.out.println(q.set.getRandom());
    14     }
    15     class RandomizedSet {
    16         HashMap<Integer,Integer> map;
    17         ArrayList<Integer> list;
    18         /** Initialize your data structure here. */
    19         public RandomizedSet() {
    20             map = new HashMap();
    21             list = new ArrayList<>();
    22         }
    23 
    24         /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    25         public boolean insert(int val) {
    26             //判断是否包含可以用map或者set,但是set不能存下标
    27             if (!map.containsKey(val))
    28             {
    29                 //key存数据,value存它在list中的下标
    30                 map.put(val,list.size());
    31                 list.add(val);
    32                 return true;
    33             }
    34             else
    35                 return false;
    36         }
    37 
    38         /** Removes a value from the set. Returns true if the set contained the specified element. */
    39         public boolean remove(int val) {
    40             if (map.containsKey(val))
    41             {
    42                 //删除:要想map中的value不用全部变,只能删除的时候list的下标不全部改变(list默认删除后后边的元素会向前挪),多以采取的方法:
    43                 //先把list最后一个元素num覆盖到指定位置(借助map获取位置),再删除最后一个元素,然后map修改num的value,再删除val那条数据
    44                 //最后一个元素
    45                 int num = list.get(list.size()-1);
    46                 //覆盖(也可以两个元素交换)
    47                list.set(map.get(val),num);
    48                //删除最后一个元素
    49                list.remove(list.size()-1);
    50                //改变num的下标
    51                map.put(num,map.get(val));
    52                //删除val这条数据
    53                map.remove(val);
    54                return true;
    55             }
    56             else
    57                 return false;
    58         }
    59 
    60         /** Get a random element from the set. */
    61         public int getRandom() {
    62             Random random = new Random();
    63             //随机获取下标进行取数
    64             return list.get(random.nextInt(list.size()));
    65         }
    66     }
    67 
    68 /**
    69  * Your RandomizedSet object will be instantiated and called as such:
    70  * RandomizedSet obj = new RandomizedSet();
    71  * boolean param_1 = obj.insert(val);
    72  * boolean param_2 = obj.remove(val);
    73  * int param_3 = obj.getRandom();
    74  */

     map和set可不可以组合呢,想了想好像也可以,set只负责判断包含,map的存,删,随机取,都可以O(1),有待验证

  • 相关阅读:
    Kbuild文件
    patch与diff的恩怨
    依据linux Oops信息准确定位错误代码所在行
    理解嵌入式开发中的一些硬件相关的概念
    linux内核中经常用到的设备初始化宏
    如何实例化i2c_client(四法)
    设计和编写设备驱动的一般方法
    [转] rtp h264注意点(FU-A分包方式说明)
    c语言的label后面不能直接跟变量申明
    互联网目前最有影响力的流量统计网站
  • 原文地址:https://www.cnblogs.com/stAr-1/p/7412810.html
Copyright © 2020-2023  润新知