705. Design HashSet

这一题意义还是很重大的,因为很可能面试的时候问你是怎么做的,或者有什么思路,能说几个是几个。
方法一:
针对这一题,因为元素大小有限制,所以可以直接申请一个这么大的数组,表示有没有。
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;
};
浙公网安备 33010602011771号