Design a HashSet without using any built-in hash table libraries.html
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:函數
[0, 1000000]
.[1, 10000]
.
這道題讓咱們設計HashSet,不能用自帶的哈希表的數據結構,並且要咱們主要實現添加,刪除,以及判斷是否存在,這三個函數。咱們都知道HashSet最有用的地方就是其可以在常數的時間內判斷某個元素是否存在,這都得歸功於哈希表的做用。可是如今不讓咱們用了,但咱們仍是得保證其常數級的查找效率,那麼就用空間來換時間吧。既然題目中說了數字的範圍不會超過1000000,那麼咱們就申請這麼大空間的數組,這樣對於在HashSet中的數字,咱們就將其標記爲1,不在或者刪除了的就標記爲0,檢測的時候就看其值是否爲1便可,參見代碼以下:post
解法一:優化
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個新空間。可是這樣可能會使得刪除函數變慢一些,參見代碼以下: ui
解法二:this
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; };
相似題目:url
參考資料:
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