散列(一)705. 设计哈希集合

不使用任何内建的哈希表库设计一个哈希集合
具体地说,你的设计应该包含以下的功能

 add(value):向哈希集合中插入一个值。
 contains(value) :返回哈希集合中是否存在这个值。
 remove(value):将给定值从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
 
示例:
MyHashSet hashSet = new MyHashSet();
hashSet.add(1);        
hashSet.add(2);        
hashSet.contains(1);    // 返回 true
hashSet.contains(3);    // 返回 false (未找到)
hashSet.add(2);         
hashSet.contains(2);    // 返回 true
hashSet.remove(2);         
hashSet.contains(2);    // 返回  false (已经被删除)
 
注意:
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-hashset
 
 1 //除余法构建哈希表,链地址法排除冲突
 2 //把除余法写到哈希函数里面
 3 class MyHashSet {
 4     class Node{ 
 5         int key;
 6         Node next;
 7         Node(int key, Node next){
 8             this.key = key;
 9             this.next = next;
10         }
11     }
12 
13     Node[] hashMap;
14     int p ;
15 
16     /** Initialize your data structure here. */
17     public MyHashSet() {
18         p = 30;
19         hashMap = new Node[p];
20         // for(Node node : hashMap){
21         //     node = new Node(-1,null);
22         // }
23 
24     }
25     public int hash(int key){
26         return key % p;
27     }
28     public void add(int key) {
29         if(contains(key) ) return;
30         int k = hash(key); //k就是hashcode
31         Node tmp = hashMap[k];
32         if(tmp == null) {hashMap[k] = new Node(key,null); return;} //这里不能tmp = new Node();tmp会被释放掉,并没有将新结点的地址写进去
33         while(tmp.next != null){  //走到这个k值对应的链表的尾部,这里也必须tmp.next = new Node();不然函数结束局部变量就释放了
34             tmp = tmp.next;
35         }
36         tmp.next = new Node(key,null); //如果这个key值不存在,在链尾创建新结点,如果已经存在则跳过
37     }
38     
39     public void remove(int key) {
40         if(!contains(key) ) return;
41         int k = hash(key);
42         Node cur = hashMap[k];
43         Node virHead = new Node(-1,cur); //虚拟头部
44         Node pre = virHead;
45         while(cur != null){  //走到这个k值对应的链表的尾部
46             if(cur.key == key){
47                 pre.next = cur.next;
48                 break;
49             }
50             pre = cur;
51             cur = cur.next;
52         }
53         hashMap[k] = virHead.next;
54     }
55     
56     /** Returns true if this set contains the specified element */
57     public boolean contains(int key) {
58         int k = hash(key);
59         // if(hashMap[k] == null) return false; //如果这个键对应的链表不存在,则肯定不包含这个键
60         Node tmp = hashMap[k];
61         while(tmp != null){  
62             if(tmp.key == key) return true;
63             tmp = tmp.next;
64         }
65         return false;
66     }
67 }
68 
69 /**
70  * Your MyHashSet object will be instantiated and called as such:
71  * MyHashSet obj = new MyHashSet();
72  * obj.add(key);
73  * obj.remove(key);
74  * boolean param_3 = obj.contains(key);
75  */

 

posted @ 2020-01-14 11:12  随温  阅读(319)  评论(0)    收藏  举报