Design a HashMap without using any built-in hash table libraries.
Implement the MyHashMap class:
-
MyHashMap()initializes the object with an empty map. -
void put(int key, int value)inserts a(key, value)pair into the HashMap. If thekeyalready exists in the map, update the correspondingvalue. -
int get(int key)returns thevalueto which the specifiedkeyis mapped, or-1if this map contains no mapping for thekey. -
void remove(key)removes thekeyand its correspondingvalueif the map contains the mapping for thekey.
Example 1:
Input ["MyHashMap", "put", "put", "get", "get", "put", "get", "remove", "get"] [[], [1, 1], [2, 2], [1], [3], [2, 1], [2], [2], [2]] Output [null, null, null, 1, -1, null, 1, null, -1] Explanation MyHashMap myHashMap = new MyHashMap(); myHashMap.put(1, 1); // The map is now [[1,1]] myHashMap.put(2, 2); // The map is now [[1,1], [2,2]] myHashMap.get(1); // return 1, The map is now [[1,1], [2,2]] myHashMap.get(3); // return -1 (i.e., not found), The map is now [[1,1], [2,2]] myHashMap.put(2, 1); // The map is now [[1,1], [2,1]] (i.e., update the existing value) myHashMap.get(2); // return 1, The map is now [[1,1], [2,1]] myHashMap.remove(2); // remove the mapping for 2, The map is now [[1,1]] myHashMap.get(2); // return -1 (i.e., not found), The map is now [[1,1]]
Constraints:
0 <= key, value <= 10^6- At most
10^4calls will be made toput,get, andremove.
这道题让我们设计一个 HashMap 的数据结构,不能使用自带的哈希表,跟之前那道 Design HashSet 很类似,之前那道的两种解法在这里也是行得通的,既然题目中说了数字的范围不会超过 1000000,那么就申请这么大空间的数组,只需将数组的初始化值改为 -1 即可。空间足够大了,就可以直接建立映射,移除时就将映射值重置为 -1,由于默认值是 -1,所以获取映射值就可以直接去,参见代码如下:
解法一:
class MyHashMap { public: MyHashMap() { data.resize(1e6 + 1, -1); } void put(int key, int value) { data[key] = value; } int get(int key) { return data[key]; } void remove(int key) { data[key] = -1; } private: vector<int> data; };
我们可以来适度的优化一下空间复杂度,由于存入 HashMap 的映射对儿也许不会跨度很大,那么直接就申请长度为 1000000 的数组可能会有些浪费,其实可以使用 1000 个长度为 1000 的数组来代替,那么就要用个二维数组啦,实际上开始只申请了 1000 个空数组,对于每个要处理的元素,首先对 1000 取余,得到的值就当作哈希值,对应申请的那 1000 个空数组的位置,在建立映射时,一旦计算出了哈希值,将对应的空数组 resize 为长度 1000,然后根据哈希值和 key/1000 来确定具体的加入映射值的位置。获取映射值时,计算出哈希值,若对应的数组不为空,直接返回对应的位置上的值。移除映射值一样的,先计算出哈希值,如果对应的数组不为空的话,找到对应的位置并重置为 -1。参见代码如下:
解法二:
class MyHashMap { public: MyHashMap() { data.resize(1001, vector<int>()); } void put(int key, int value) { int hashKey = key % 1000; if (data[hashKey].empty()) { data[hashKey].resize(1001, -1); } data[hashKey][key / 1000] = value; } int get(int key) { int hashKey = key % 1000; if (!data[hashKey].empty()) { return data[hashKey][key / 1000]; } return -1; } void remove(int key) { int hashKey = key % 1000; if (!data[hashKey].empty()) { data[hashKey][key / 1000] = -1; } } private: vector<vector<int>> data; };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/706
类似题目:
参考资料:
https://leetcode.com/problems/design-hashmap
https://leetcode.com/problems/design-hashmap/discuss/152746/Java-Solution
LeetCode All in One 题目讲解汇总(持续更新中...)