2019-11-27 常數(shù)時(shí)間插入、刪除和獲取隨機(jī)元素

設(shè)計(jì)一個(gè)支持在平均 時(shí)間復(fù)雜度 O(1) 下,執(zhí)行以下操作的數(shù)據(jù)結(jié)構(gòu)。

insert(val):當(dāng)元素 val 不存在時(shí),向集合中插入該項(xiàng)。
remove(val):元素 val 存在時(shí),從集合中移除該項(xiàng)。
getRandom:隨機(jī)返回現(xiàn)有集合中的一項(xiàng)。每個(gè)元素應(yīng)該有相同的概率被返回。
示例 :

// 初始化一個(gè)空的集合。
RandomizedSet randomSet = new RandomizedSet();

// 向集合中插入 1 。返回 true 表示 1 被成功地插入。
randomSet.insert(1);

// 返回 false ,表示集合中不存在 2 。
randomSet.remove(2);

// 向集合中插入 2 。返回 true 。集合現(xiàn)在包含 [1,2] 。
randomSet.insert(2);

// getRandom 應(yīng)隨機(jī)返回 1 或 2 。
randomSet.getRandom();

// 從集合中移除 1 ,返回 true 。集合現(xiàn)在包含 [2] 。
randomSet.remove(1);

// 2 已在集合中,所以返回 false 。
randomSet.insert(2);

// 由于 2 是集合中唯一的數(shù)字,getRandom 總是返回 2 。
randomSet.getRandom();

注意

1、c++的類體中,方法以外的區(qū)域不允許有初始化,簡(jiǎn)單類型是可以的,但是有構(gòu)造函數(shù)的復(fù)雜對(duì)象則不行了,比如int對(duì)象!也可以手動(dòng)調(diào)用reverse分配空間。

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

2、C++產(chǎn)生隨機(jī)數(shù)的函數(shù),srandrand。當(dāng)程序連續(xù)需要調(diào)用隨機(jī)數(shù)時(shí),不要每次都按照時(shí)鐘定義隨機(jī)數(shù)種子,這樣會(huì)使得其反,由于程序運(yùn)行很快毫秒級(jí),使得每次設(shè)置的種子都一樣,導(dǎo)致每次生成所有的隨機(jī)數(shù)都一樣,從而無(wú)法通過(guò)?。?!

一般推薦寫成:srand((unsigned)time(NULL));或者srand((unsigned)time(0));

關(guān)于time_t time(0)
time_t被定義為長(zhǎng)整型,它返回從1970年1月1日零時(shí)零分零秒到目前為止所經(jīng)過(guò)的時(shí)間,單位為

C++1
class RandomizedSet {
private:
    vector<int> v; //存放數(shù)字
    map<int, int> m; //存放數(shù)字和下標(biāo)的映射
    int index;
    int flag;
public:
    /** Initialize your data structure here. */
    RandomizedSet() {
        v.reserve(10000); //分配足夠大的空間,不然報(bào)錯(cuò):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]; //數(shù)組末尾的值
            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));  // 如果是用這個(gè)函數(shù)定義隨機(jī)種子,由于測(cè)試時(shí)會(huì)一直運(yùn)行g(shù)etRandom函數(shù),導(dǎo)致每次選出的結(jié)果都一樣,從而失敗
        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();
 */
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容