在常数时间插入、删除和获取随机元素

设计一个集合,要求插入和删除都是O(1),并且可以等概率随机返回任意数字

很巧妙的一个点:如何在O(1)删除?虽然你通过哈希表已经找到了这个元素,但是如果他在数组的中间?你要删除不调用erase函数,这样使得整个数组的位置都发生了错乱,并且不是一个O(1)的操作。

解决办法:

我们不需要从中把他删除,直接把找到的元素a给置换到数组的最后一位,然后pop_back就是O(1)了,当然这里不用真正的交换,因为你本来就要删除,直接把元素赋值就可以,然后更新一下原来最后一位的哈希表位置就可以了。

380. 常数时间插入、删除和获取随机元素

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.find(val) != m.end())  return false;
        data.push_back(val);
        int index  = data.size()-1;
        m[val] = index;
        return true;
    }
    
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    bool remove(int val) {
        auto iter = m.find(val);
        if(iter == m.end()) return false;
        int pos = iter->second;
        data[pos] = data.back();
        m[data.back()] = pos;
        data.pop_back();
        m.erase(iter);
        return true;
    }
    
    /** Get a random element from the set. */
    int getRandom() {
        if(data.size() == 0)    return -1;
        int pos = rand() % data.size();
        return data[pos];
    }
    vector data;
    unordered_map m;
};

 

你可能感兴趣的:(面经中遇到问题)