码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-08-10 12:41:32      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

 

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

 

这题是之前那道Insert Delete GetRandom O(1)的拓展,与其不同的是,之前那道题不能有重复数字,而这道题可以有,那么就不能像之前那道题那样建立每个数字和其坐标的映射了,但是我们可以建立数字和其所有出现位置的集合之间的映射,虽然写法略有不同,但是思路和之前那题完全一样,都是将数组最后一个位置的元素和要删除的元素交换位置,然后删掉最后一个位置上的元素。对于insert函数,我们将要插入的数字在nums中的位置加入m[val]数组的末尾,然后在数组nums末尾加入val,我们判断是否有重复只要看m[val]数组只有刚加的val一个值还是有多个值。remove函数是这题的难点,我们首先看哈希表中有没有val,没有的话直接返回false。然后我们取出nums的尾元素,把尾元素哈希表中的位置数组中的最后一个位置更新为m[val]的尾元素,这样我们就可以删掉m[val]的尾元素了,如果m[val]只有一个元素,那么我们把这个映射直接删除。然后我们将nums数组中的尾元素删除,并把尾元素赋给val所在的位置,参见代码如下:

 

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

 

类似题目:

Insert Delete GetRandom O(1)

 

参考资料:

https://discuss.leetcode.com/topic/53659/c-two-solutions

 

LeetCode All in One 题目讲解汇总(持续更新中...)

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

标签:

原文地址:http://www.cnblogs.com/grandyang/p/5756148.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!