zoukankan      html  css  js  c++  java
  • LeetCode 380. Insert Delete GetRandom O(1) 常数时间插入、删除和获取随机元素(C++/Java)

    题目:

    Design a data structure that supports all following operations in averageO(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();

    分析:

    设计一个数据结构支持以下几个操作。

    insert(val): 当元素 val 不存在时,向集合中插入该项。
    remove(val): 元素 val 存在时,从集合中移除该项。
    getRandom: 随机返回现有集合中的一项。每个元素应该有相同的概率被返回。

    我们使用HashMap来支持插入和移除操作,利用数组来支持对数据的随机访问。插入元素时,将val和该val在数组中索引值存入map中,新插入的元素实际上在数组中的索引就是数组还有元素的个数,将元素加到动态数组的尾端。

    移除元素时,为了能够达到O(1),除了将val在map中移除,还要对数组进行操作,如果单纯的将val所对应的索引处的元素删除,由于后续的所有元素都要向前移动,这样会浪费大量的时间。我们知道数组移除最后一个元素的时间复杂度时O(1),我们将要移除的元素和数组的最后一个元素交换,也可以将最后一个元素覆盖到要移除元素的位置,同时修改最后一个元素在map中对应的索引,最后删除掉数组最后一个元素,就可以保证常数时间的移除操作。最后在数组大小的范围内产生随机数,返回对应的元素,即可实现随机访问。

    程序:

    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;
            m[val] = v.size();
            v.push_back(val);
            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 index = m[val];
            m[v.back()] = index;
            v[index] = v.back();
            m.erase(val);
            v.pop_back();
            return true;
        }
        
        /** Get a random element from the set. */
        int getRandom() {
            int index = rand() % v.size();
            return v[index];
        }
    private:
        unordered_map<int, int> m;
        vector<int> v;
    };

    Java

    class RandomizedSet {
    
        /** Initialize your data structure here. */
        public RandomizedSet() {
            
        }
        
        /** 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, list.size());
            list.add(val);
            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))
                return false;
            int index = map.get(val);
            map.put(list.get(list.size()-1), index);
            list.set(index, list.get(list.size()-1));
            list.remove(list.size()-1);
            map.remove(val);
            return true;
        }
        
        /** Get a random element from the set. */
        public int getRandom() {
            Random r = new Random();
            return list.get(r.nextInt(list.size()));
        }
        private HashMap<Integer, Integer> map = new HashMap<>();
        private ArrayList<Integer> list = new ArrayList<>();
    }
  • 相关阅读:
    Jedis 源代码阅读一 —— Jedis
    Java中的${pageContext.request.contextPath}
    VMware Workstation 12 安装mac os x 10.11
    机器学习——朴素贝叶斯分类器
    Codeforces 138C(区间更新+离散化)
    Threejs 官网
    深刻理解Nginx之Nginx完整安装
    Apache + Tomcat 负载均衡 session复制
    小P寻宝记——好基友一起走
    C++数值类型极限值的获取
  • 原文地址:https://www.cnblogs.com/silentteller/p/12245330.html
Copyright © 2011-2022 走看看