题目:
不使用任何内建的哈希表库设计一个哈希映射(HashMap)。
实现 MyHashMap
类:
MyHashMap()
用空映射初始化对象void put(int key, int value)
向 HashMap 插入一个键值对(key, value)
。如果key
已经存在于映射中,则更新其对应的值value
。int get(int key)
返回特定的key
所映射的value
;如果映射中不包含key
的映射,返回-1
。void remove(key)
如果映射中存在key
的映射,则移除key
和它所对应的value
。
提示:
0 <= key, value <= 106
- 最多调用
104
次put
、get
和remove
方法
思考:
超大数组
第一眼:这题不是跟昨天的705题差不多吗?......然后用超大数组的写法写了,也通过了:
class MyHashMap(object):
def __init__(self):
self.hash = [-1] * 1000001
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: None
"""
self.hash[key] = value
def get(self, key):
"""
:type key: int
:rtype: int
"""
return self.hash[key]
def remove(self, key):
"""
:type key: int
:rtype: None
"""
self.hash[key] = -1
提交通过:
那么用正经哈希函数写呢?
哈希函数+链地址法(定长数组)
即用二维数组的索引代表key值,数值代表value值。设置行数volume为1000,同时也是哈希函数中的除数。哈希函数即:
1. address(key所在的行) = key % volume,可见address的范围为[0, 999]。
2. address_ (key所在的列)= key // self.volume,可见address_的范围为[0, 1000]。所以设置数组的列数为1001。
代码如下:
class MyHashMap(object):
def __init__(self):
# key的范围:[0, 1000000]
self.volume = 1000
# 1000行(代表除数为1000,也代表余数从0到999)
self.hashmap = [[-1]*1001 for _ in range(self.volume)]
# 1001列(代表整除商,从0到1000)
def _hash(self, key):
address = key % self.volume # 第一层位置(行)
address_ = key // self.volume # 第二层位置(列)
return address, address_
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: None
"""
address, address_ = self._hash(key)
self.hashmap[address][address_] = value
def get(self, key):
"""
:type key: int
:rtype: int
"""
address, address_ = self._hash(key)
return self.hashmap[address][address_]
def remove(self, key):
"""
:type key: int
:rtype: None
"""
address, address_ = self._hash(key)
self.hashmap[address][address_] = -1
提交通过:
【最优】哈希函数+链地址法(变长列表)
思路跟昨天的题一模一样,只不过向列表中插入的不再是key值,而是[key, value]小数组。代码如下:
class MyHashMap(object):
def __init__(self):
self.volume = 1000
self.hashset = [[] for _ in range(self.volume)]
def _hash(self, key):
return key % self.volume # 哈希函数
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: None
"""
index = self._hash(key)
for item in self.hashset[index]:
if item[0] == key:
# 如果key已经存在于映射中,则更新其对应的值 value
item[1] = value
return
self.hashset[index].append([key, value])
# 若key还不存在,则插入[key, value]
def get(self, key):
"""
:type key: int
:rtype: int
"""
index = self._hash(key)
for item in self.hashset[index]:
if item[0] == key:
return item[1]
return -1
def remove(self, key):
"""
:type key: int
:rtype: None
"""
index = self._hash(key)
for i, item in enumerate(self.hashset[index]):
if item[0] == key:
del self.hashset[index][i]
提交通过: