LeetCode 706:Design HashMap 實現一個簡單的雜湊對映
阿新 • • 發佈:2019-01-06
題目描述:
Design a HashMap without using any built-in hash table libraries.
To be specific, your design should include these functions:
put(key, value)
: Insert a (key, value) pair into the HashMap. If the value already exists in the HashMap, update the value.get(key)
: Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key.remove(key)
: Remove the mapping for the value key if this map contains the mapping for the key.
Example:
MyHashMap hashMap = new MyHashMap();
hashMap.put(1, 1);
hashMap.put(2, 2);
hashMap.get(1); // returns 1
hashMap.get(3); // returns -1 (not found)
hashMap.put(2 , 1); // update the existing value
hashMap.get(2); // returns 1
hashMap.remove(2); // remove the mapping for 2
hashMap.get(2); // returns -1 (not found)
Note:
All keys and values will be in the range of [0, 1000000]
.
The number of operations will be in the range of [1, 10000]
Please do not use the built-in HashMap library.
題解
題目大意:
題目意思其實很簡單,就是設計一個HashMap包含題目給出的幾個函式,不能使用內建的HashMap庫。
實現:
正好最近在用python嘗試構建hash表,順道把這道題也一起解了。
用Python實現的一個簡單的Hash表,採用hash函式是取餘,用線性探測解決衝突問題。
class HashTable:
# 初始化
def __init__(self, size):
self.elem = [None for i in range(size)] # 建立一個列表儲存雜湊元素,值全為None
self.count = size # 最大表長
# 雜湊函式
def hash(self, key):
return key % self.count # 雜湊函式採用除留餘數法
# 插入
def insert_hash(self, key):
print(key)
address = self.hash(key) # 計算雜湊地址
print(address)
while self.elem[address] != None: # 發生衝突
address = (address + 1) % self.count # 線性探測解決衝突
print(address)
self.elem[address] = key # 沒有衝突
print(self.elem)
# 查詢
def search_hash(self, key):
star = address = self.hash(key) # 查詢關鍵字
while self.elem[address] != key:
address = (address + 1) % self.count
if not self.elem[address] or address == star: # 說明沒找到或者迴圈到了開始的位置
return False
return True
if __name__ == '__main__':
list_a = [0, 12, 67, 56, 16, 25, 37, 22, 29, 15, 47, 48, 34]
hash_table = HashTable(len(list_a))
for i in list_a:
hash_table.insert_hash(i)
for i in hash_table.elem:
if i:
print((i, hash_table.elem.index(i)))
print(hash_table.search_hash(15))
print(hash_table.search_hash(33))
針對這道題,也可以採用取餘作為hash函式,採用“拉鍊法”處理衝突,將相同hash值的物件組織成一個連結串列放在hash值對應的位置;具體原理和Java中的HashMap
實現的原理類似。具體程式碼如下:
class MyHashMap:
def __init__(self):
"""
Initialize your data structure here.
"""
self.buckets = 1000 # 鍵值塊,雜湊桶
self.itemsPerBuckect = 1001 # 產生衝突的“拉鍊”塊
self.hashmap = [[] for _ in range(self.buckets)] # _表示臨時變數,僅用一次,後面無需用到
# 雜湊函式
def hash(self, key):
return key % self.buckets # 取餘
# 處理衝突的函式
def pos(self, key):
return key // self.buckets # 向下取整,返回商的整數部分
def put(self, key, value):
"""
value will always be positive.
:type key: int
:type value: int
:rtype: void
"""
hashkey = self.hash(key)
if not self.hashmap[hashkey]: # 沒有產生衝突,直接填入buckets中
self.hashmap[hashkey] = [None] * self.itemsPerBuckect
self.hashmap[hashkey][self.pos(key)] = value
def get(self, key):
"""
Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key
:type key: int
:rtype: int
"""
hashkey = self.hash(key)
if(not self.hashmap[hashkey]) or self.hashmap[hashkey][self.pos(key)] == None: # 沒有找到這個值
return -1
else:
return self.hashmap[hashkey][self.pos(key)]
def remove(self, key):
"""
Removes the mapping of the specified value key if this map contains a mapping for the key
:type key: int
:rtype: void
"""
hashkey = self.hash(key)
if self.hashmap[hashkey]:
self.hashmap[hashkey][self.pos(key)] = None
if __name__ == "__main__":
hashmap = MyHashMap()
hashmap.put(1, 1)
hashmap.put(2, 2)
hashmap.get(1)
hashmap.get(3)
hashmap.put(2, 1)
hashmap.get(2)
hashmap.remove(2)
hashmap.get(2)
python極簡版本:
class MyHashMap:
def __init__(self):
self.arr = [-1] * 1000001
def put(self, key, value):
self.arr[key] = value
def get(self, key):
return self.arr[key]
def remove(self, key):
self.arr[key] = -1
c++實現版本,直接用vector容器模擬,沒有考慮衝突情況。
class MyHashMap {
public:
/** Initialize your data structure here. */
vector<int> hashMap;
MyHashMap() {
}
/** value will always be non-negative. */
void put(int key, int value) {
if(key >= hashMap.size()){
for(int i = hashMap.size(); i <= key; i++){
hashMap.push_back(-1);
}
}
hashMap[key] = value;
}
/** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
int get(int key) {
if(key >= hashMap.size())
return -1;
return hashMap[key];
}
/** Removes the mapping of the specified value key if this map contains a mapping for the key */
void remove(int key) {
if(key >= hashMap.size())
return;
hashMap[key] = -1;
}
};