705. 设计哈希集合
不使用任何内建的哈希表库设计一个哈希集合(HashSet)。
实现 MyHashSet 类:
void add(key) 向哈希集合中插入值 key 。
bool contains(key) 返回哈希集合中是否存在这个值 key 。
void remove(key) 将给定值 key 从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-hashset
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
1.构建哈希函数
2.冲突处理:
2.1链地址法
2.2开放地址法
2.3再哈希法
3.扩容
我的答案:
import java.util.LinkedList;
class MyHashSet {
private static final int BASE=769;
private LinkedList[] data;
/** Initialize your data structure here. */
public MyHashSet() {
data=new LinkedList[BASE];
for (int i = 0; i < BASE; i++) {
data[i]=new LinkedList<Integer>();
}
}
public void add(int key) {
int t=hash(key);
if(data[t].contains(key)){
return;
}
data[t].add(key);
}
public void remove(int key) {
int t=hash(key);
for (int i = 0; i < data[t].size(); i++) {
if((int)data[t].get(i)==key){
data[t].remove(i);
break;
}
}
}
/** Returns true if this set contains the specified element */
public boolean contains(int key) {
int t=hash(key);
if(data[t].contains(key)){
return true;
}
return false;
}
public int hash(int k){
return k%BASE;
}
}
时间效率超过95%的方法(位运算)
此题很容易想到用一个长数组解决,需要注意边界情况,长度为1000001;
长数组的缺点是,空间效率很低,在哈希表的实现中,用了数组+链表的结构,我们可以借鉴。
下面介绍另外一种用位运算的解法。一个位代表一个数,int 类型有32位,
可以代表32个数,需要31250个整数才能表达0-999999,这里也要注意边界情况,所以数组长度要设为31251.
剩下的就是如何找到对应的位置:
数组的索引idx = key / 32;用位运算就是 key >> 5;
位索引 bitIdx = key % 32
add(key)时,将对应的位设为1,numArr[idx] |= 1 << bitIdx;
remove(key)时,将对应的位设为0,numArr[idx] &= (~(1 << bitIdx));
class MyHashSet {
int[] numArr;
/** Initialize your data structure here. */
public MyHashSet() {
numArr = new int[31251];
}
public void add(int key) {
setKey(key, true);
}
public void remove(int key) {
setKey(key, false);
}
/** Returns true if this set contains the specified element */
public boolean contains(int key) {
return getKey(key);
}
private void setKey(int key, boolean add) {
int idx = key >> 5;
int bitIdx = key % 32;
if(add) {
numArr[idx] |= 1 << bitIdx;
} else {
numArr[idx] &= (~(1 << bitIdx));
}
}
private boolean getKey(int key) {
int idx = key >> 5;
int bitIdx = key % 32;
return (numArr[idx] >> bitIdx & 1) == 1;
}
}
// 作者:chu-ting
// 链接:https://leetcode-cn.com/problems/design-hashset/solution/java-wei-yun-suan-gao-kong-jian-xiao-lu-r2ouz/
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。