美文网首页LeeCode题目笔记
2019-11-27 常数时间插入、删除和获取随机元素

2019-11-27 常数时间插入、删除和获取随机元素

作者: Antrn | 来源:发表于2019-11-27 17:56 被阅读0次

    设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构。

    insert(val):当元素 val 不存在时,向集合中插入该项。
    remove(val):元素 val 存在时,从集合中移除该项。
    getRandom:随机返回现有集合中的一项。每个元素应该有相同的概率被返回。
    示例 :

    // 初始化一个空的集合。
    RandomizedSet randomSet = new RandomizedSet();
    
    // 向集合中插入 1 。返回 true 表示 1 被成功地插入。
    randomSet.insert(1);
    
    // 返回 false ,表示集合中不存在 2 。
    randomSet.remove(2);
    
    // 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
    randomSet.insert(2);
    
    // getRandom 应随机返回 1 或 2 。
    randomSet.getRandom();
    
    // 从集合中移除 1 ,返回 true 。集合现在包含 [2] 。
    randomSet.remove(1);
    
    // 2 已在集合中,所以返回 false 。
    randomSet.insert(2);
    
    // 由于 2 是集合中唯一的数字,getRandom 总是返回 2 。
    randomSet.getRandom();
    

    注意

    1、c++的类体中,方法以外的区域不允许有初始化,简单类型是可以的,但是有构造函数的复杂对象则不行了,比如int对象!也可以手动调用reverse分配空间。

    class C{
    private:
        vector<int> v(9);  //error,expected identifier before numeric constant
    public:
    void test(){}
    };
    

    2、C++产生随机数的函数,srandrand。当程序连续需要调用随机数时,不要每次都按照时钟定义随机数种子,这样会使得其反,由于程序运行很快毫秒级,使得每次设置的种子都一样,导致每次生成所有的随机数都一样,从而无法通过!!!

    一般推荐写成:srand((unsigned)time(NULL));或者srand((unsigned)time(0));

    关于time_t time(0)
    time_t被定义为长整型,它返回从1970年1月1日零时零分零秒到目前为止所经过的时间,单位为

    C++1
    class RandomizedSet {
    private:
        vector<int> v; //存放数字
        map<int, int> m; //存放数字和下标的映射
        int index;
        int flag;
    public:
        /** Initialize your data structure here. */
        RandomizedSet() {
            v.reserve(10000); //分配足够大的空间,不然报错:AddressSanitizer: heap-buffer-overflow on address 0x602000000114 at pc 0x000000416046 bp 0x7ffd7453cd20 sp 0x7ffd7453cd18
            index = 0; //v的大小
            flag = 1;
        }
        
        /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
        bool insert(int val) {
            if(m.count(val)>0){
                return false;
            }else{
                if(flag == 1){
                    v.push_back(val);
                    flag = 0;
                }else{
                    v[index] = val;
                }
                
                m.insert(make_pair(val, index++));
                return true;
            }
        }
        
        /** Removes a value from the set. Returns true if the set contained the specified element. */
        bool remove(int val) {
            if(m.count(val)>0){
                int t = v[index-1]; //数组末尾的值
                m[t] = m[val];
                v[m[val]] = t;
                m.erase(val);
                index--;
                return true;
            }else{
                return false;
            }
        }
        
        /** Get a random element from the set. */
        int getRandom() {
            //srand((int)time(0));  // 如果是用这个函数定义随机种子,由于测试时会一直运行getRandom函数,导致每次选出的结果都一样,从而失败
            int num = rand()%index;
            return v[num];
        }
    };
    
    /**
     * 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();
     */
    

    相关文章

      网友评论

        本文标题:2019-11-27 常数时间插入、删除和获取随机元素

        本文链接:https://www.haomeiwen.com/subject/stcmwctx.html