网络编程
位置:首页>> 网络编程>> Go语言>> Go语言题解LeetCode705设计哈希集合

Go语言题解LeetCode705设计哈希集合

作者:刘09k11  发布时间:2024-03-19 22:30:38 

标签:Go,LeetCode,设计,哈希集合

题目描述

705. 设计哈希集合

不使用任何内建的哈希表库设计一个哈希集合(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);
*/

来源:https://juejin.cn/post/7179208586210312251

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com