[M設計+雜湊表] lc380. 常數時間插入、刪除和獲取隨機元素(設計+雜湊表)

Y_puyu發表於2020-10-31

1. 題目來源

連結:lc380. 常數時間插入、刪除和獲取隨機元素

2. 題目說明

在這裡插入圖片描述

3. 題目解析

設計資料結構,實現三個操作:

  • O ( 1 ) O(1) O(1) 插入
  • O ( 1 ) O(1) O(1) 刪除
  • O ( 1 ) O(1) O(1) 等概率返回一個隨機值

當然,插入、刪除 O ( 1 ) O(1) O(1) 的話雜湊表就能搞定,但是雜湊表不支援等概率返回這個操作,需要有一個支援隨機索引的資料結構,那麼就是陣列了。

開一個雜湊表,建一個陣列:

  • 插入時在陣列末尾插入,在雜湊表中維護該數在陣列下的下標,即 <val, index>
  • 返回隨機值,陣列支援隨機索引,等概率返回任一數即可
  • 刪除,雜湊表可以 O ( 1 ) O(1) O(1) 刪除。陣列僅支援末尾 O ( 1 ) O(1) O(1) 刪除。那麼基於這個思想,我們可以把需要刪除的數放到陣列最後一個位置,然後直接 pop_back(),達到 O ( 1 ) O(1) O(1) 刪除。 當然,也需要在雜湊表中將對應索引進行交換。

這也是陣列實現 O ( 1 ) O(1) O(1) 刪除一個元素的方法,將該元素與末尾元素進行交換後刪除。

程式碼:

class RandomizedSet {
public:
    unordered_map<int, int> hash;
    vector<int> nums;

    /** 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 (hash.count(val) == 0) {
            nums.push_back(val);
            hash[val] = nums.size() - 1;
            return true;
        }
        return false;
    }
    
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    bool remove(int val) {
        if (hash.count(val)) {
            int y = nums.back();
            int pval = hash[val], py = hash[y];
            swap(nums[pval], nums[py]);
            swap(hash[val], hash[y]);
            nums.pop_back();
            hash.erase(val);
            return true;
        }
        return false;
    }
    
    /** Get a random element from the set. */
    int getRandom() {
        return nums[rand() % nums.size()];
    }
};

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

相關文章