-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdesign-hashset.go
95 lines (83 loc) · 1.94 KB
/
design-hashset.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package main
// source: https://leetcode.com/problems/design-hashset/
// Ways to improve:
// 1. Use better collision resolving strategies
// 2. Rebuild hash-table when bucket size gets bigger than some value
const capacity = 100
type BucketNode struct {
key int
next *BucketNode
}
type MyHashSet struct {
buckets []*BucketNode
}
func Constructor() MyHashSet {
set := MyHashSet{
buckets: make([]*BucketNode, capacity),
}
lastNode := &BucketNode{
next: nil,
key: -1,
}
for i := 0; i < capacity; i++ {
set.buckets[i] = lastNode
}
return set
}
func hashFunc(val int) (hash int) {
return val % capacity
}
func (s *MyHashSet) Add(key int) {
prevNode, hash := s.findPrev(key)
if prevNode == nil || prevNode.key != -1 {
return
}
node := &BucketNode{
key: key,
next: s.buckets[hash],
}
s.buckets[hash] = node
}
func (s *MyHashSet) findPrev(key int) (*BucketNode, int) {
hash := hashFunc(key)
prevNode := s.buckets[hash]
if prevNode.key == key {
return nil, hash
}
for prevNode.next != nil && prevNode.next.key != key {
prevNode = prevNode.next
}
return prevNode, hash
}
func (s *MyHashSet) Remove(key int) {
node, hash := s.findPrev(key)
if node == nil {
s.buckets[hash] = s.buckets[hash].next
} else if node.key != -1 {
node.next = node.next.next
}
}
func (s *MyHashSet) Contains(key int) bool {
if tmp, _ := s.findPrev(key); tmp != nil && tmp.key == -1 {
return false
}
return true
}
/**
* Your s object will be instantiated and called as such:
* obj := Constructor();
* obj.Add(key);
* obj.Remove(key);
* param_3 := obj.Contains(key);
*/
func main() {
s := Constructor()
s.Add(1) // set = [1]
s.Add(2) // set = [1, 2]
println(s.Contains(1)) // return True
println(s.Contains(3)) // return False, (not found)
s.Add(2) // set = [1, 2]
println(s.Contains(2)) // return True
s.Remove(2) // set = [1]
println(s.Contains(2)) // return False, (already removed)
}