380. O(1) 时间插入、删除和获取随机元素

这道题主要考察O(1)的时间复杂度
对于增加和删除操作,可以通过可变长数组实现O(1)的时间复杂度
对于查询操作,可以通过hash表实现O(1)的时间复杂度
于是这道题就是两个数据结构相结合。
使用可变长数组存储元素,方便增加和删除,使用hash表存储元素的对应下标,方便查询。

设置两个数据容器的时候在private区域设置

在初始化部分设置随机种子,使用time(NULL)来获取当前时间,并转化为unsigned形式,然后传入到srand()函数中,设置随机种子,每次获取的时间不同,随机种子不同。

增加操作
首先判断hash表中是否有val,如果有,返回false,如果没有,在nums数组里增加元素(使用emplace_back避免复制拷贝元素节省时间),并在hash表中记录其下标,返回true

删除操作
首先判断hash表中是否有val,如果没有,返回false,如果有,则找到val的下标,将nums的最后一个元素nums.back()放到val的位置,更新最后一个元素在hash表中的下标,然后删除nums中最后一个元素,删除hash表中val的下标,返回true

随机化操作
获取一个随机数对nums.size()取余,然后从nums数组中取出并返回。

class RandomizedSet {
public:
    RandomizedSet() {
        srand((unsigned)time(NULL));
    }
    
    bool insert(int val) {
        if (indices.count(val)) return false;
        int index = nums.size();
        nums.emplace_back(val);
        indices[val] = index;
        return true;
    }
    
    bool remove(int val) {
        if (!indices.count(val)) return false;
        int index = indices[val];
        int last = nums.back();
        nums[index] = last;
        indices[last] = index;
        // nums.pop_back(val);
        nums.pop_back();
        indices.erase(val);
        return true;
    }
    
    int getRandom() {
        int randomIndex = rand() % nums.size();
        return nums[randomIndex];
    }
private:
    vector<int> nums;
    unordered_map<int, int> indices;
};

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

你可能感兴趣的:(LeetCode,哈希算法,算法,数据结构)