[LeetCode] 706. Design HashMap 设计HashMap
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 thekey
already exists in the map, update the correspondingvalue
.int get(int key)
returns thevalue
to which the specifiedkey
is mapped, or-1
if this map contains no mapping for thekey
.void remove(key)
removes thekey
and its correspondingvalue
if 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^4
calls 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