【LeetCode705】设计哈希集合(哈希)
原创
©著作权归作者所有:来自51CTO博客作者wx62cea850b9e28的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、题目

提示:
- 0 <= key <= 10^6
- 最多调用 104 次 add、remove 和 contains
二、思路
哈希表有个2个关键问题:
- 哈希函数:将任意值通过哈希函数映射到固定值,可以设哈希表的大小为
,输入哈希函数值为
,设计一个简单的哈希函数:
。其中
一般取为质数,可以取987。 - 哈希表一般使用链地址法,即让每个vector元素是一个链表
list
。对哈希表的增删改查都是通过hash函数计算后,对这个list
进行增删改查即可。
PS:
- 对
vector<list<int>>a
进行初始化大小时,如果是直接用vector<list<int>>a(987);
是会报错的,可以定义后再用a.resize(987)
,但是这样是产生对象后才扩容到987,效率更快的写法是:MyHashSet():a(987){}
,即在构造a时就是987大小了。 - 在C++的STL中,map或者set可以直接使用
find
,但是vector或者list是不可以直接使用find
的。
三、代码
class MyHashSet {
private:
vector<list<int>>a;
int base = 987;
int hash(int key){
return key % base;
}
public:
MyHashSet(){
a.resize(987);
}
void add(int key) {
int temp = hash(key);
for(auto it = a[temp].begin(); it != a[temp].end(); it++){
if(*it == key){
return;
}
}
a[temp].push_back(key);
}
void remove(int key) {
int temp = hash(key);
for(auto it = a[temp].begin(); it != a[temp].end(); it++){
if(*it == key){
//注意这里不能写成erase(key)
a[temp].erase(it);
return;
}
}
}
bool contains(int key) {
int temp = hash(key);
for(auto it = a[temp].begin(); it != a[temp].end(); it++){
if(*it == key){
return true;
}
}
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);
*/
