[LeetCode] Design HashSet 設計HashSet


 

Design a HashSet without using any built-in hash table libraries.

To be specific, your design should include these functions:

  • add(value): Insert a value into the HashSet. 
  • contains(value) : Return whether the value exists in the HashSet or not.
  • remove(value): Remove a value in the HashSet. If the value does not exist in the HashSet, do nothing.


Example:

MyHashSet hashSet = new MyHashSet();
hashSet.add(1);         
hashSet.add(2);         
hashSet.contains(1);    // returns true
hashSet.contains(3);    // returns false (not found)
hashSet.add(2);          
hashSet.contains(2);    // returns true
hashSet.remove(2);          
hashSet.contains(2);    // returns false (already removed)


Note:

    • All values will be in the range of [0, 1000000].
    • The number of operations will be in the range of [1, 10000].
    • Please do not use the built-in HashSet library.

 

這道題讓我們設計HashSet,不能用自帶的哈希表的數據結構,而且要我們主要實現添加,刪除,以及判斷是否存在,這三個函數。我們都知道HashSet最有用的地方就是其能夠在常數的時間內判斷某個元素是否存在,這都得歸功於哈希表的作用。但是現在不讓我們用了,但我們還是得保證其常數級的查找效率,那么就用空間來換時間吧。既然題目中說了數字的范圍不會超過1000000,那么我們就申請這么大空間的數組,這樣對於在HashSet中的數字,我們就將其標記為1,不在或者刪除了的就標記為0,檢測的時候就看其值是否為1即可,參見代碼如下:

 

解法一:

class MyHashSet {
public:
    /** Initialize your data structure here. */
    MyHashSet() {
        data.resize(1000000, 0);
    }
    
    void add(int key) {
        data[key] = 1;
    }
    
    void remove(int key) {
        data[key] = 0;
    }
    
    /** Returns true if this set contains the specified element */
    bool contains(int key) {
        return data[key] == 1;
    }
    
private:
    vector<int> data;
};

 

我們可以來適度的優化一下空間復雜度,由於存入HashSet的數字也許不會跨度很大,那么直接就申請長度為1000000的數組可能會有些浪費,那么我們其實可以使用1000個長度為1000的數組來代替,那么就要用個二維數組啦,實際上開始我們只申請了1000個空數組,對於每個要處理的元素,我們首先對1000取余,得到的值就當作哈希值,對應我們申請的那1000個空數組的位置,在加入元素時,一旦計算出了哈希值,我們將對應的空數組resize為長度1000,然后根據哈希值和key/1000來確定具體的加入位置。移除數字一樣的,先計算出哈希值,如果對應的數組不為空的話,找到對應的位置並賦值為0。不過大家也可以看出來,我們在加入元素時會開辟1000的新空間,但是刪除這個元素時,並沒有檢測這1000個位置是否均為0,是的話應該刪除這1000個新空間。但是這樣可能會使得刪除函數變慢一些,參見代碼如下: 

 

解法二:

class MyHashSet {
public:
    /** Initialize your data structure here. */
    MyHashSet() {
        data.resize(1000, vector<int>());
    }
    
    void add(int key) {
        int hashKey = key % 1000;
        if (data[hashKey].empty()) {
            data[hashKey].resize(1000);
        } 
        data[hashKey][key / 1000] = 1;
    }
    
    void remove(int key) {
        int hashKey = key % 1000;
        if (!data[hashKey].empty()) {
            data[hashKey][key / 1000] = 0;
        } 
    }
    
    /** Returns true if this set contains the specified element */
    bool contains(int key) {
        int hashKey = key % 1000;
        return !data[hashKey].empty() && data[hashKey][key / 1000];
    }
    
private:
    vector<vector<int>> data;
};

 

類似題目:

Design HashMap

 

參考資料:

https://leetcode.com/problems/design-hashset/

https://leetcode.com/problems/design-hashset/discuss/185826/C%2B%2B-solution

https://leetcode.com/problems/design-hashset/discuss/193132/Solution-without-boolean-array

https://leetcode.com/problems/design-hashset/discuss/143434/Beats-100-Real-Java-Solution-(Not-boolean-array)

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM