题目链接:https://leetcode-cn.com/problems/design-hashset/
设计一个哈希集合
题目:
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 (已经被删除)
注意:
- 所有的值都在
[1, 1000000]
的范围内。 - 操作的总数目在
[1, 10000]
范围内。 - 不要使用内建的哈希集合库。
这题有几种方法可以解决,比如直接创建1000000个int 的内存,利用下标,但过于暴力,我将把定址哈希用在位上,这样可以节省到 1/32的内存。也可以使用链表法,不过具体我没实现。
C方法一:用这种方法myHashSetContains( )函数有点麻烦,但不妨解决。
#define SIZE 20000
typedef struct {
int* hash;
int* visited;
} MyHashSet;
/** Initialize your data structure here. */
MyHashSet* myHashSetCreate() {
MyHashSet* H = (MyHashSet*)malloc(sizeof(MyHashSet));
H->hash = (int*)malloc(sizeof(int)* SIZE);
H->visited = (int*)malloc(sizeof(int)* SIZE);
memset(H->hash,0,sizeof(int)* SIZE);
memset(H->visited,0,sizeof(int)* SIZE);
return H;
}
int myhashfun(int k)
{
return (k % SIZE);
}
void myHashSetAdd(MyHashSet* obj, int key) {
int t = myhashfun(key);
while (obj->visited[t] != 0 && obj->hash[t] != key)
t = myhashfun(t+1);
if (obj->visited[t] == 0)
{
obj->hash[t] = key;
obj->visited[t] = 1;
}
}
void myHashSetRemove(MyHashSet* obj, int key) {
int t = myhashfun(key);
while (obj->visited[t] != 0 && obj->hash[t] != key)
t = myhashfun(t+1);
if (obj->hash[t] == key)
{
//obj->hash[t] = 0;
obj->visited[t] = 0;
}
}
/** Returns true if this set did not already contain the specified element */
bool myHashSetContains(MyHashSet* obj, int key) {
int t = myhashfun(key);
while (obj->visited[t] != 0 && obj->hash[t] != key)
t = myhashfun(t+1);
if (obj->visited[t] != 0 && obj->hash[t] == key)
return true;
int count = 0;
while (count < SIZE){
if (obj->visited[t] == 0 && obj->hash[t] == 0)
return false;
t = myhashfun(t+1);
count++;
if (obj->hash[t] == key)
return true;
}
return false;
}
void myHashSetFree(MyHashSet* obj) {
free(obj->hash);
free(obj->visited);
free(obj);
}
/**
* Your MyHashSet struct will be instantiated and called as such:
* struct MyHashSet* obj = myHashSetCreate();
* myHashSetAdd(obj, key);
* myHashSetRemove(obj, key);
* bool param_3 = myHashSetContains(obj, key);
* myHashSetFree(obj);
*/
C方法二:利用 1 byte == 8 bit
#define SIZE (1000001/8)
typedef struct {
unsigned char * hash;
} MyHashSet;
/** Initialize your data structure here. */
MyHashSet* myHashSetCreate() {
MyHashSet* H = (MyHashSet*)malloc(sizeof(MyHashSet));
H->hash = (int*)malloc(sizeof(unsigned char)* SIZE);
memset(H->hash,0,sizeof(unsigned char)* SIZE);
return H;
}
void myHashSetAdd(MyHashSet* obj, int key) {
int pos = key / 8;
int t = key % 8;
obj->hash[pos] |= 1 << t ;
}
void myHashSetRemove(MyHashSet* obj, int key) {
int pos = key / 8;
int t = key%8;
obj->hash[pos] &= ~(1 << t) ;
}
/** Returns true if this set did not already contain the specified element */
bool myHashSetContains(MyHashSet* obj, int key) {
int pos = key / 8;
int t = key%8;
return obj->hash[pos] & (1 << t) ;
}
void myHashSetFree(MyHashSet* obj) {
free(obj->hash);
free(obj);
}
谢谢。