题目:
不使用任何内建的哈希表库设计一个哈希集合(HashSet)。
实现 MyHashSet 类:
void add(key)向哈希集合中插入值key。bool contains(key)返回哈希集合中是否存在这个值key。void remove(key)将给定值key从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
算法:
方法一:数组法
略。
方法二:位运算
我们用一个int32(int64也可以)表示32个数,每个位上不为0则表示数据存在。数据量10e6 / 32 = 31,250,因此我们最多需要不超过40000个int32。
1.每个int32作为一个bucket,每个bucket内存储32个数。
2.定位bucket的方法:bucketId := num / 32
3.定位buckect内的方法: id := num % 32
type MyHashSet struct {
bucket []int
}
func Constructor() MyHashSet {
return MyHashSet{make([]int, 40000)}
}
func (this *MyHashSet) Add(key int) {
bocketId := key / 32
id := key % 32
this.Set(bocketId, id, true)
}
func (this *MyHashSet) Remove(key int) {
bocketId := key / 32
id := key % 32
this.Set(bocketId, id, false)
}
func (this *MyHashSet) Contains(key int) bool {
bocketId := key / 32
id := key % 32
return true == this.Exist(bocketId, id)
}
func (this *MyHashSet) Set(bucket, id int, val bool) {
if val {
this.bucket[bucket] = this.bucket[bucket] | (1 << id)
} else {
this.bucket[bucket] = this.bucket[bucket] & (^(1 << id))
}
}
func (this *MyHashSet) Exist(bucket, id int) bool {
return this.bucket[bucket] & (1 << id) != 0
}
/**
* Your MyHashSet object will be instantiated and called as such:
* obj := Constructor();
* obj.Add(key);
* obj.Remove(key);
* param_3 := obj.Contains(key);
*/
方法三:链表法
链表法本质上是一个二维数组,数据范围1000000,所以平衡地取一个二维数组则是1000 * 1000(避免链表过长或者二维数组长度过长)。我们向上取一个比1000大地质数1009作为二维数组长度。 (为上面要取质数呢?)
type MyHashMap struct {
List [][][]int
Len int
}
func Constructor() MyHashMap {
m := MyHashMap{make([][][]int, 1000), 1000}
return m
}
func (this *MyHashMap) Put(key int, value int) {
idx := key % this.Len
for i, item := range this.List[idx] {
if item[0] == key {
this.List[idx][i][1] = value
return
}
}
this.List[idx] = append(this.List[idx], []int{key, value})
// fmt.Println(this.List[:5])
}
func (this *MyHashMap) Get(key int) int {
idx := key % this.Len
for _, item := range this.List[idx] {
if item[0] == key {
return item[1]
}
}
return -1
}
func (this *MyHashMap) Remove(key int) {
idx := key % this.Len
n := len(this.List[idx])
i := 0
exist := false
for ; i < n; i ++ {
if this.List[idx][i][0] == key {
exist = true
break
}
}
// 将要移除的元素交换到数组最后,然后移除数组最后一个元素
if exist {
this.List[idx][i], this.List[idx][n - 1] = this.List[idx][n - 1], this.List[idx][i]
this.List[idx] = this.List[idx][:n - 1]
}
}