【LeetCode】Insert Delete GetRandom O(1) 系列

Insert Delete GetRandom O(1) 系列

380. Insert Delete GetRandom O(1)

介绍

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

insert(val): Inserts an item val to the set if not already present.

remove(val): Removes an item val from the set if present.

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

解答

使用一个unordered_map和vector来进行数据的存储。

vector用于实际的数据存储,unordered_map中存储着数据和vector中相应的下标。

  1. insert(val): 先在unordered_map中查找val,查找成功则返回false。否则则直接在vector的最后添加val,并在unordered_map中添加映射关系。
  2. remove(val):先在unordered_map中查找val,查找失败则返回false。否则,先在unordered_map确定val在vector的下标值,然后将vector的最后一个元素换到这个位置,然后删除最后一个元素,同时需要注意更新mapping中的映射关系,并删除相应元素。
  3. 对vector的大小做模,然后取相应元素。
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(mapping.find(val) != mapping.end()) return false;
        mapping[val] = nums.size();
        nums.emplace_back(val);
        return true;
    }

    /** Removes a value from the set. Returns true if the set contained the specified element. */
    bool remove(int val) {
        if(mapping.find(val) == mapping.end()) return false;
        int last = nums.size()-1;
        int cur = mapping[val];
        mapping[nums[last]] = cur;
        nums[cur] = nums[last];
        nums.pop_back();
        mapping.erase(val);
        return true;
    }

    /** Get a random element from the set. */
    int getRandom() {
        return (nums[rand()%nums.size()]);
    }
    vector<int> nums;
    unordered_map<int,int> mapping;
};

/**
 * Your RandomizedSet object will be instantiated and called as such:
 * RandomizedSet obj = new RandomizedSet();
 * bool param_1 = obj.insert(val);
 * bool param_2 = obj.remove(val);
 * int param_3 = obj.getRandom();
 */

381. Insert Delete GetRandom O(1) - Duplicates allowed

介绍

Design a data structure that supports all following operations in average O(1) time.
Note: Duplicate elements are allowed.

insert(val): Inserts an item val to the collection.

remove(val): Removes an item val from the collection if present.

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

题意: 本题比上题目的难度要稍大,主要是因为允许重复元素的插入。

解答

本题中依然采取一个unordered_map

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) {
        bool res;
        unordered_map<int,vector<int>>::iterator it = mapping.find(val);
        if(it == mapping.end() || it->second.empty())  //collection中不存在元素val
        {
            nums.emplace_back(val,0);
            mapping[val].emplace_back(nums.size()-1);
            res = true;
        }else
        {
            nums.emplace_back(val,it->second.size());
            it->second.emplace_back(nums.size()-1);
            res = false;
        }
        return res;
    }

    /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    bool remove(int val) {
        unordered_map<int,vector<int>>::iterator it = mapping.find(val);
        if(it == mapping.end() || it->second.empty()) return false;

        int cur = it->second.back();
        int last = nums.size()-1;
        nums[cur] = nums[last];
        it->second.pop_back();
        nums.pop_back();
        unordered_map<int,vector<int>>::iterator it_last = mapping.find(nums[cur].first);
        it_last->second[nums[cur].second] = cur;
        return true;
    }

    /** Get a random element from the collection. */
    int getRandom() {
        return (nums[rand()%nums.size()].first);
    }
    vector<pair<int,int>> nums;
    unordered_map<int,vector<int>> mapping;
};

/**
 * 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();
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值