LeetCode Notes_#706_设计哈希映射
Contents
题目
不使用任何内建的哈希表库设计一个哈希映射
具体地说,你的设计应该包含以下的功能
put(key, value)
:向哈希映射中插入(键,值)的数值对。如果键对应的值已经存在,更新这个值。get(key)
:返回给定的键所对应的值,如果映射中不包含这个键,返回-1。remove(key)
:如果映射中存在这个键,删除这个数值对。
注意:
- 所有的值都在
[0, 1000000]
的范围内。 - 操作的总数目在
[1, 10000]
范围内。 - 不要使用内建的哈希库。
思路分析
与设计HashSet
一题是类似的,核心思路在于把要存储的数据利用哈希函数(散列函数)来分布到各个桶当中,然后再调用桶的增删查改方法,在桶里进行具体的操作。
与HashSet
的不同之处在于,我们这里不仅仅保存一个Key
,还得保存一个Value
,所以桶内部的数据类型需要自己定义一个Pair
类型。
看起来函数很多,以为很复杂,技巧是先在纸上把所有函数,类列出来,设计好每个函数的功能,返回值等,然后再写代码,就不容易乱了。
解答
//Pair对象用来存储键值对
class Pair<U,V>{
public U first;
public V second;
public Pair(U first, V second){
this.first = first;
this.second = second;
}
}
//Bucket对象作为桶,存储Pair对象
class Bucket{
List<Pair<Integer, Integer>> bucket;
public Bucket(){
bucket = new LinkedList<>();
}
public void bucket_add(int key, int value){
//ERROR:这里需要用一个flag做标识
boolean found = false;
//如果存在这个key,就更新它
for(Pair<Integer,Integer> pair:bucket){
if(pair.first == key){
pair.second = value;
found = true;
}
}
//如果不存在这个key,直接插入新的键值对
if(!found) bucket.add(new Pair<Integer,Integer>(key, value));
}
public int bucket_get(int key){
for(Pair<Integer,Integer> pair:bucket){
if(pair.first == key) return pair.second;
}
return -1;
}
public void bucket_remove(int key){
for(Pair<Integer,Integer> pair:bucket){
if(pair.first == key){
//ERROR:找到对应的key之后需要break跳出循环
bucket.remove(pair);
break;
}
}
}
}
class MyHashMap {
int bucketNum = 769;
Bucket[] bucketArray;
/** Initialize your data structure here. */
public MyHashMap() {
bucketArray = new Bucket[bucketNum];
for(int i = 0;i < bucketNum;i++){
bucketArray[i] = new Bucket();
}
}
private int hash(int key){
return key % bucketNum;
}
/** value will always be non-negative. */
public void put(int key, int value) {
int bucketIndex = hash(key);
bucketArray[bucketIndex].bucket_add(key, value);
}
/** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
public int get(int key) {
int bucketIndex = hash(key);
return bucketArray[bucketIndex].bucket_get(key);
}
/** Removes the mapping of the specified value key if this map contains a mapping for the key */
public void remove(int key) {
int bucketIndex = hash(key);
bucketArray[bucketIndex].bucket_remove(key);
}
}
复杂度分析
时间复杂度:O(N/K)
,N是所有键值对的数量,K是桶的数量
空间复杂度:O(K+M)
,K是桶的数量,M是已经插入的键值对的数量