Go语言题解LeetCode705设计哈希集合
刘09k11 人气:0题目描述
不使用任何内建的哈希表库设计一个哈希集合(HashSet)。
实现 MyHashSet 类:
- void add(key) 向哈希集合中插入值 key 。
- bool contains(key) 返回哈希集合中是否存在这个值 key 。
- void remove(key) 将给定值 key 从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。 示例:
输入: ["MyHashSet", "add", "add", "contains", "contains", "add", "contains", "remove", "contains"] [[], [1], [2], [1], [3], [2], [2], [2], [2]] 输出: [null, null, null, true, false, null, true, null, false] 解释: MyHashSet myHashSet = new MyHashSet(); myHashSet.add(1); // set = [1] myHashSet.add(2); // set = [1, 2] myHashSet.contains(1); // 返回 True myHashSet.contains(3); // 返回 False ,(未找到) myHashSet.add(2); // set = [1, 2] myHashSet.contains(2); // 返回 True myHashSet.remove(2); // set = [1] myHashSet.contains(2); // 返回 False ,(已移除)
提示:
- 0 <= key <= 10^6
- 最多调用 10^4 次 add、remove 和 contains
思路分析
实现使用了链地址法,解决哈希冲突方法使用了模取余的方法(较简单的)。
这里说下为什么大家说模最好取质数,我的理解是取质数可以让取余后的结果更加均匀,以减少冲突。
举个例子,假如我们取4为模,那么虽然理论上我们应该会让数字均匀落入4个桶中,但是对于下边这个数组:
1,3,5,7,9
所有数字都落入了1,3两个桶中,造成了极大的不均,导致哈希冲突发生频繁。对于一个合数,只要我们构造合数倍数相关的数组,就很容易使哈希冲突变多,所以尽量选用质数。
AC 代码
struct Listnode{ int val; Listnode* next = nullptr; Listnode()=default; Listnode(int val){ this->val = val; } }; class MyHashSet { public: /** Initialize your data structure here. */ const int prime = 991; vector<Listnode*> nodes; MyHashSet(): nodes(prime, nullptr){ } void add(int key) { if(nodes[key%prime] == nullptr){ nodes[key%prime] = new Listnode(key); }else{ Listnode* node = nodes[key%prime]; while(node != nullptr){ if(node->val == key)return; node = node->next; } node = new Listnode(key); node->next = nodes[key%prime]; nodes[key%prime] = node; } } void remove(int key) { Listnode* prenode = nodes[key%prime]; if(prenode != nullptr && prenode->val == key){ if(prenode->next != nullptr){ nodes[key%prime] = prenode->next; delete prenode; }else{ delete prenode; nodes[key%prime] = nullptr; } return; } while(prenode != nullptr && prenode->next != nullptr){ if(prenode->next->val == key){ Listnode* temp = prenode->next; prenode->next = prenode->next->next; delete temp; return; } prenode = prenode->next; } } /** Returns true if this set contains the specif ied element */ bool contains(int key) { Listnode* node = nodes[key%prime]; while(node != nullptr){ if(node->val == key)return true; node = node->next; } return false; } }; /** * Your MyHashSet object will be instantiated and called as such: * MyHashSet* obj = new MyHashSet(); * obj->add(key); * obj->remove(key); * bool param_3 = obj->contains(key); */
加载全部内容