面试经典题---380.O(1)时间插入、删除和获取随机元素E

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

参考解法:

        由于题目要求O(1)内以相等的概率随机返回集合中的一项,因此这道题不能单独使用unordered_set,需要使用数组和哈希表结合的方法。

1.定义一个容量足够大的数组nums,用于存放各个元素val;

2.哈希表my_map的键存放val,值存放val在数组nums中对应的下标;

        变量range用于记录元素数目,即数组nums中[0,range]范围的都是有效元素;

        my_map[val]是元素val在数组nums中的下标,将哈希表与数组关联起来。

插入元素时:

  1. 若val已存在于哈希表中,则返回false;
  2. 否则,将val存入数组nums中,并更新range,在my_map中插入元素val及其下标;

 删除元素时:

  1. 若val不存在,直接返回false;
  2. 否则,先用pos记录元素val在数组nums中的下标——my_map[val],之后用nums中的末尾元素nums[range]填补待删除元素nums[pos],并更新末尾元素nums[range]在哈希表中的下标值(更新为pos),注意更新range。

        使用数组nums来为各个元素绑定一个下标,保证元素分布在numsd的[0,range]下标范围内,从而实现以相同的概率随机访问元素。

const int N = 200000;
int nums[N],range;

class RandomizedSet {
public:
    RandomizedSet() {
        range = -1;
    }
    
    bool insert(int val) {
        if(!my_map.count(val)){
            nums[++range] = val;
            my_map[val] = range;
            return true;
        }
        return false;
    }
    
    bool remove(int val) {
        if(my_map.count(val)){
            int pos = my_map[val];
            my_map.erase(val);
            if(pos != range) my_map[nums[range]] = pos;
            nums[pos] = nums[range--];
            return true;
        }
        return false;
    }
    
    int getRandom() {
        return nums[rand() % (range + 1)];
    }
private:
    unordered_map<int,int> my_map;
};

  • 22
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值