這一題意義還是很重大的,因爲很可能面試的時候問你是怎麼做的,或者有什麼思路,能說幾個是幾個。
方法一:
針對這一題,因爲元素大小有限制,所以可以直接申請一個這麼大的數組,表示有沒有。
class MyHashSet {
public:
/** Initialize your data structure here. */
MyHashSet():values(1000001, false) {
}
void add(int key) {
values[key] = true;
}
void remove(int key) {
values[key] = false;
}
/** Returns true if this set contains the specified element */
bool contains(int key) {
return values[key];
}
private:
vector<bool> values;
};
方法二:
如果數據範圍不限制的話,可以使用二維表,其實還是使用了hash表,使用了類似拉鍊法來解決衝突,這裏大小可以自己設定,根據數據量多少來設置,一般設定爲素數
class MyHashSet {
public:
/** Initialize your data structure here. */
MyHashSet():table(sz, vector<int>()) {
}
void add(int key) {
int idx = key % sz;
for (int num : table[idx])
if (num == key)
return;
table[idx].push_back(key);
}
void remove(int key) {
int idx = key % sz;
for (int i = 0; i < table[idx].size(); ++i) {
if (table[idx][i] == key) {
table[idx].erase(table[idx].begin()+i);
return;
}
}
}
/** Returns true if this set contains the specified element */
bool contains(int key) {
int idx = key % sz;
for (int num : table[idx])
if (num == key)
return true;
return false;
}
private:
int sz = 1001;
vector<vector<int>> table;
};
至於爲什麼使用素數:
待補充
https://blog.csdn.net/w_y_x_y/article/details/82288178
https://blog.csdn.net/maoliran/article/details/52082829
除數取合數的話,一旦數據是以合數的某個因子爲間隔增長的,那麼哈希值只會是幾個值不停的重複,衝突很嚴重,而素數就不會發生這種情況。
方法三:
BST。也就是有序的map(紅黑樹和avl不會實現。。。)。這裏的話優點是能夠保證有序性,缺點是時間可能退化爲線性
struct Node {
Node(int v): val(v), left(nullptr), right(nullptr) {}
int val;
Node* left;
Node* right;
};
class BST {
public:
BST(): root(nullptr) {}
void insert(int v) {
root = insertHelper(root, v);
}
void erase(int v) {
root = eraseHelper(root, v);
}
bool find(int v) {
return findHelper(root, v);
}
private:
Node* root;
Node* insertHelper(Node* node, int v) {
if (!node)
return new Node(v);
if (node->val == v)
return node;
if (node->val > v)
node->left = insertHelper(node->left, v);
else
node->right = insertHelper(node->right, v);
return node;
}
Node* eraseHelper(Node* node, int v) {
if (!node)
return nullptr;
if (v < node->val)
node->left = eraseHelper(node->left, v);
else if (v > node->val)
node->right = eraseHelper(node->right, v);
else {
Node* retNode = nullptr;
if (!node->left) {
retNode = node->right;
delete node;
} else if (!node->right) {
retNode = node->left;
delete node;
} else {
retNode = node->right;
auto node2 = node->right;
while (node2->left)
node2 = node2->left;
node2->left = node->left;
delete node;
}
node = retNode;
}
return node;
}
Node* findHelper(Node* node, int v) {
if (!node)
return nullptr;
if (v < node->val)
return findHelper(node->left, v);
else if (v > node->val)
return findHelper(node->right, v);
else
return node;
}
};
class MyHashSet {
public:
/** Initialize your data structure here. */
MyHashSet(): bst(new BST()) {
}
void add(int key) {
bst->insert(key);
}
void remove(int key) {
bst->erase(key);
}
/** Returns true if this set contains the specified element */
bool contains(int key) {
return bst->find(key);
}
private:
BST* bst;
};