1. 问题描述:
不使用任何内建的哈希表库设计一个哈希集合(HashSet)。实现 MyHashSet 类:
void add(key) 向哈希集合中插入值 key 。
bool contains(key) 返回哈希集合中是否存在这个值 key 。
void remove(key) 将给定值 key 从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
示例:
输入:
["MyHashSet", "add", "add", "contains", "contains", "add", "contains", "remove", "contains"]
[[], [1], [2], [1], [3], [2], [2], [2], [2]]
输出:
[null, null, null, true, false, null, true, null, false]
解释:
MyHashSet myHashSet = new MyHashSet();
myHashSet.add(1); // set = [1]
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(1); // 返回 True
myHashSet.contains(3); // 返回 False ,(未找到)
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(2); // 返回 True
myHashSet.remove(2); // set = [1]
myHashSet.contains(2); // 返回 False ,(已移除)
提示:
0 <= key <= 10 ^ 6
最多调用 10 ^ 4 次 add、remove 和 contains 。
进阶:你可以不使用内建的哈希集合库解决此问题吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-hashset
2. 思路分析:
因为使用的是python语言,所以可以使用二维列表来模拟哈希表,我们可以使用类似于桶排序的思路,第一维表示一个桶的编号,第二维表示桶编号对应的key值,我们在添加元素到哈希表中的时候先使用一个比较大的质数n计算出当前的key在哪一个桶,如果发现桶中存在当前的key则不做任何修改的操作直接返回即可,如果发现对应的桶中不存在当前的key那么将当前的key插入到对应桶的编号中即可;删除元素的时候也是类似地,先计算出当前的key对应的桶中是否存在当前的key,存在则删除元素;判断当前的key是否存在哈希表中可以先计算出当前的key对应的桶的编号,在桶中查找对应key是否存在即可。
3. 代码如下:
class MyHashSet:
n = 0
hash = None
def __init__(self):
# n为质数
self.n = 19997
# 使用列表来模拟哈希表
self.hash = [list() for i in range(self.n)]
# 在哈希中查找是否存在这样的key, 辅助find方法
def find(self, key: int):
hash = self.hash
_key = key % self.n
if key in hash[_key]: return key
return -1
# 往哈希表中添加key
def add(self, key: int) -> None:
_key = key % self.n
hash = self.hash
t = self.find(key)
if t != -1: return
hash[_key].append(key)
# 移除掉哈希表中的键
def remove(self, key: int) -> None:
_key = key % self.n
t = self.find(key)
if t == -1: return
self.hash[_key].remove(key)
# 哈希表中是否存在这样的key
def contains(self, key: int) -> bool:
_key = key % self.n
t = self.find(key)
if key in self.hash[_key]: return True
return False