LeetCode - 380. Insert Delete GetRandom O(1)-思路详解

本文详细介绍了LeetCode第380题的解决方案,设计一个数据结构,支持在平均O(1)时间内进行插入、删除和获取随机元素的操作。通过使用哈希映射和动态调整数组位置来实现高效操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题

Design a data structure that supports all following operations in average O(1) time.
1,insert(val): Inserts an item val to the set if not already present.
2,remove(val): Removes an item val from the set if present.
3,getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.

题目翻译

设计一个数据结构,该数据可以在O(1)时间内完成以下操作:
1,insert(val):插入一个元素到集合中,如果元素之前不存在。
2,remove(val):如果val在集合中存在,则删除
3,getRandom:返回当前集合中随机的一个数。每个元素返回的概率相同。

思路解析

由于题目要求删除和插入的时间复杂度均为O(1)。首先想到使用数组保存所有数据。这样的话,插入时间复杂度为O(n)。但是删除数据的时间复杂度为O(n)。随机返回操作时间复杂度为O(n)。如何实现O(1)。我们使用一个map来保存数据-位置关系。然后使用vector来保存元素。
1,insert操作。首先判断val在map中是否存在,时间复杂度为O(1)。如果存在,则返回false。否则,将数据插入到vector中。然后在map中保存数据-位置键值对。时间复杂度为O(1)

2,remove操作。首先判断val在map中是否存在,时间复杂度为O(1)。如果不存在,则返回false。否则,首先将val的所在位置保存vector尾部元素的值。修改尾部数据的在map中的位置映射。以及val的位置映射。然后删除val在map中映射关系。然后删除vector中最后一个元素。此时时间负责度为O(1)

3,getRandom操作。有rand()函数产生随机的位置pos。然后返回vector中pos处的元素即可

代码

class RandomizedSet {
public:
    map<int,int> data_map;  //数字 - 对应位置
    vector<int> data;
    /** 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(data_map.count(val) != 0){
            return false;
        }else{
            data.push_back(val);   //在数组中插入该值
            data_map[val] = data.size()-1;      //在map中加入该值和数组中的位置对应
            return true;
        }
    }

    /** Removes a value from the set. Returns true if the set contained the specified element. */
    bool remove(int val) {
        //查找是是否在map中存在,如果不存在则返回false
        if(data_map.count(val) == 0){
            return false;
        }else{
            //否则,和数组尾部数据位置交换,删除掉尾部数据
            int tail = data[data.size()-1];
            int pos1 = data_map[val];   //获取需要删除数据的位置
            int pos2 = data.size()-1;  //最后一个元素的位置
            data_map[tail] = pos1;
            data_map[val] = pos2;
            data[pos1] = tail;      //将需要删除的元素和尾部元素交换
            data_map.erase(val);    //删除哈希表中的数据
            data.pop_back();        //删除数组中的data
            return true;
        }
    }

    /** Get a random element from the set. */
    int getRandom() {
        int t = data.size();
        int random_num = rand()%t;
        return data[random_num];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值