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

2022-12-29 08:54:50
目录
题目描述思路分析AC 代码

题目描述

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);
       */

      以上就是Go语言题解LeetCode705设计哈希集合的详细内容,更多关于Go语言设计哈希集合的资料请关注易采站长站其它相关文章!