zoukankan      html  css  js  c++  java
  • [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 1 is the only number in the set, getRandom always return 1.
    randomSet.getRandom();

    设计一个数据结构在O(1)时间内完成:insert(val),remove(val),getRandom()

    由于是O(1)时间,要用哈希表 + 数组(HashMap + Array),数组用来保存数字,哈希表用来建立每个数字和其在数组中的位置之间的映射。

    插入操作:先判断是否在HashMap里,如果存在则不需要插入,直接返回false。不存在的话,把此数插入到数组的末尾,然后在HashMap中建立数字和其位置的映射。

    删除操作:先判断是否在HashMap里,如果没有,直接返回false。由于HashMap的删除是O(1)时间,而数组并不是。为了保证了O(1)时间内的删除,把要删除的数字和数组的最后一个数调换个位置,然后修改对应的HashMap中的值,删除数组的最后一个元素即可。

    返回随机数:随机生成一个数组位置,返回该位置上的数字。

    Java:

    public class RandomizedSet {
        Map<Integer, Integer> map;//<val, index in arrlist>
        List<Integer> list;//keep a record of value for get random 
        int size;//map and list are the same size
        Random rand;
        /** Initialize your data structure here. */
        public RandomizedSet() {
            this.map = new HashMap<>();
            this.list = new ArrayList<>();
            this.size = 0;
            this.rand = new Random();
        }
        
        /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
        public boolean insert(int val) {
            if(map.containsKey(val)) return false;
            map.put(val, size);
            list.add(val);
            size++;
            return true;
        }
        
        /** Removes a value from the set. Returns true if the set contained the specified element. */
        public boolean remove(int val) {
            if(map.containsKey(val)){
                int last = list.get(size - 1);
                list.set(map.get(val), last);//use last added ele to fill the element to be removed 
                map.put(last, map.get(val));//update last added ele's index in list
                map.remove(val);
                list.remove(size - 1);//remove at end is constant
                size--;
                return true;
            }
            return false;
        }
        
        /** Get a random element from the set. */
        public int getRandom() {
            return list.get(rand.nextInt(size));
        }
    }
    

    Python:

    import random
    class RandomizedSet(object):
    
        def __init__(self):
            """
            Initialize your data structure here.
            """
            self.dataMap = {}
            self.dataList = []
    
        def insert(self, val):
            """
            Inserts a value to the set. Returns true if the set did not already contain the specified element.
            :type val: int
            :rtype: bool
            """
            if val in self.dataMap:
                return False
            self.dataMap[val] = len(self.dataList)
            self.dataList.append(val)
            return True
    
        def remove(self, val):
            """
            Removes a value from the set. Returns true if the set contained the specified element.
            :type val: int
            :rtype: bool
            """
            if val not in self.dataMap:
                return False
            idx = self.dataMap[val]
            tail = self.dataList.pop()
            if idx < len(self.dataList):
                self.dataList[idx] = tail
                self.dataMap[tail] = idx
            del self.dataMap[val]
            return True
    
        def getRandom(self):
            """
            Get a random element from the set.
            :rtype: int
            """
            return random.choice(self.dataList)  

    C++:

    class RandomizedSet {
    public:
        /** Initialize your data structure here. */
        RandomizedSet() {}
        
        /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
        bool insert(int val) {
            if (m.count(val)) return false;
            nums.push_back(val);
            m[val] = nums.size() - 1;
            return true;
        }
        
        /** Removes a value from the set. Returns true if the set contained the specified element. */
        bool remove(int val) {
            if (!m.count(val)) return false;
            int last = nums.back();
            m[last] = m[val];
            nums[m[val]] = last;
            nums.pop_back();
            m.erase(val);
            return true;
        }
        
        /** Get a random element from the set. */
        int getRandom() {
            return nums[rand() % nums.size()];
        }
    private:
        vector<int> nums;
        unordered_map<int, int> m;
    };
    

    类似题目:

    [LeetCode] 381. Insert Delete GetRandom O(1) - Duplicates allowed 插入删除和获得随机数O(1)时间 - 允许重复  

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    C#根据url生成唯一的key
    MyBatis基本配置和实践(四)
    MyBatis基本配置和实践(三)
    MyBatis基本配置和实践(二)
    MyBatis基本配置和实践(一)
    dbcp2、c3p0、druid连接池的简单配置
    HTTP长连接和短连接
    Java Web高性能开发
    三层构架 和 MVC 是什么?
    Docker bridge探索
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8512237.html
Copyright © 2011-2022 走看看