• 381. Insert Delete GetRandom O(1)


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

    Note: Duplicate elements are allowed.

    1. insert(val): Inserts an item val to the collection.
    2. remove(val): Removes an item val from the collection if present.
    3. getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.

    Example:

    // Init an empty collection.
    RandomizedCollection collection = new RandomizedCollection();
    
    // Inserts 1 to the collection. Returns true as the collection did not contain 1.
    collection.insert(1);
    
    // Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1].
    collection.insert(1);
    
    // Inserts 2 to the collection, returns true. Collection now contains [1,1,2].
    collection.insert(2);
    
    // getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3.
    collection.getRandom();
    
    // Removes 1 from the collection, returns true. Collection now contains [1,2].
    collection.remove(1);
    
    // getRandom should return 1 and 2 both equally likely.
    collection.getRandom();

    Approach #1: C++.

    class RandomizedCollection {
    public:
        /** Initialize your data structure here. */
        RandomizedCollection() {
            
        }
        
        /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
        bool insert(int val) {
            auto result = m.find(val) == m.end();
            
            m[val].push_back(nums.size());
            nums.push_back(pair<int, int>(val, m[val].size() - 1));
            
            return result;
        }
        
        /** Removes a value from the collection. Returns true if the collection contained the specified element. */
        bool remove(int val) {
            if (!m.count(val)) return false;
            else {
                auto last = nums.back();
                m[last.first][last.second] = m[val].back();
                nums[m[val].back()] = last;
                m[val].pop_back();
                if (m[val].empty()) m.erase(val);
                nums.pop_back();
                return true;
            }
        }
        
        /** Get a random element from the collection. */
        int getRandom() {
            return nums[rand() % nums.size()].first;
        }
    private:
        vector<pair<int, int>> nums;
        unordered_map<int, vector<int>> m;
    };
    
    /**
     * Your RandomizedCollection object will be instantiated and called as such:
     * RandomizedCollection obj = new RandomizedCollection();
     * bool param_1 = obj.insert(val);
     * bool param_2 = obj.remove(val);
     * int param_3 = obj.getRandom();
     */
    

      

    In this solution we use vector<pair<int, int>> nums to resoter the numbers in the set,  using the unordered_map<int, vector<int>> to restore the position of the number.

    Runtime: 36 ms, faster than 82.83% of C++ online submissions for Insert Delete GetRandom O(1) - Duplicates allowed.

    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    立则存
    如何在UI控件上绑定一个变量
    欢迎大家使用www.eugene.org.cn访问我的blog
    属性与字段变量的区别
    在C#中联合Excel的Com编程入门
    我和我的土匪奶奶 全集 全 下载 txt
    大菲波数
    Hat's Fibonacci
    Fibonacci 取余,直接做超时
    How Many Fibs? 字符串转换处理
  • 原文地址:https://www.cnblogs.com/h-hkai/p/9966570.html
Copyright © 2020-2023  润新知