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的数据结构,不能使用自带的哈希表,跟之前那道 Design HashSet 很类似,之前那道的两种解法在这里也是行得通的,既然题目中说了数字的范围不会超过 1000000,那么就申请这么大空间的数组,只需将数组的初始化值改为 -1 即可。空间足够大了,就可以直接建立映射,移除时就将映射值重置为 -1,由于默认值是 -1,所以获取映射值就可以直接去,参见代码如下:

解法一:

class MyHashMap {
public:
MyHashMap() {
data.resize(, -);
}
void put(int key, int value) {
data[key] = value;
}
int get(int key) {
return data[key];
}
void remove(int key) {
data[key] = -;
} private:
vector<int> data;
};

我们可以来适度的优化一下空间复杂度,由于存入 HashMap 的映射对儿也许不会跨度很大,那么直接就申请长度为 1000000 的数组可能会有些浪费,其实可以使用 1000 个长度为 1000 的数组来代替,那么就要用个二维数组啦,实际上开始只申请了 1000 个空数组,对于每个要处理的元素,首先对 1000 取余,得到的值就当作哈希值,对应申请的那 1000 个空数组的位置,在建立映射时,一旦计算出了哈希值,将对应的空数组 resize 为长度 1000,然后根据哈希值和 key/1000 来确定具体的加入映射值的位置。获取映射值时,计算出哈希值,若对应的数组不为空,直接返回对应的位置上的值。移除映射值一样的,先计算出哈希值,如果对应的数组不为空的话,找到对应的位置并重置为 -1。参见代码如下:

解法二:

class MyHashMap {
public:
MyHashMap() {
data.resize(, vector<int>());
}
void put(int key, int value) {
int hashKey = key % ;
if (data[hashKey].empty()) {
data[hashKey].resize(, -);
}
data[hashKey][key / ] = value;
}
int get(int key) {
int hashKey = key % ;
if (!data[hashKey].empty()) {
return data[hashKey][key / ];
}
return -;
}
void remove(int key) {
int hashKey = key % ;
if (!data[hashKey].empty()) {
data[hashKey][key / ] = -;
}
} private:
vector<vector<int>> data;
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/706

类似题目:

Design HashSet

参考资料:

https://leetcode.com/problems/design-hashmap

https://leetcode.com/problems/design-hashmap/discuss/152746/Java-Solution

https://leetcode.com/problems/design-hashmap/discuss/184764/Easy-C%2B%2B-Solution-beats-98.01(52-msec)-using-array-of-vectors

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Design HashMap 设计HashMap的更多相关文章

  1. [LeetCode] Design HashSet 设计HashSet

    Design a HashSet without using any built-in hash table libraries. To be specific, your design should ...

  2. [LeetCode] Design Twitter 设计推特

    Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and ...

  3. [LeetCode] Design Tic-Tac-Toe 设计井字棋游戏

    Design a Tic-tac-toe game that is played between two players on a n x n grid. You may assume the fol ...

  4. [LeetCode] Design TinyURL 设计精简URL地址

    Note: For the coding companion problem, please see: Encode and Decode TinyURL. How would you design ...

  5. LeetCode 622:设计循环队列 Design Circular Queue

    LeetCode 622:设计循环队列 Design Circular Queue 首先来看看队列这种数据结构: 队列:先入先出的数据结构 在 FIFO 数据结构中,将首先处理添加到队列中的第一个元素 ...

  6. HashMap设计原理与实现(下篇)200行带你写自己的HashMap!!!

    HashMap设计原理与实现(下篇)200行带你写自己的HashMap!!! 我们在上篇文章哈希表的设计原理当中已经大体说明了哈希表的实现原理,在这篇文章当中我们将自己动手实现我们自己的HashMap ...

  7. [Java] 遍历HashMap和HashMap转换成List的两种方式

    遍历HashMap和HashMap转换成List   /** * convert the map to the list(1) */ public static void main(String[] ...

  8. Java基础知识强化之集合框架笔记62:Map集合之HashMap嵌套HashMap

    1. HashMap嵌套HashMap  传智播客          jc    基础班                      陈玉楼  20                      高跃   ...

  9. == 和 equals,equals 与 hashcode,HashSet 和 HashMap,HashMap 和 Hashtable

    一:== 和 equals == 比较引用的地址equals 比较引用的内容 (Object 类本身除外) String obj1 = new String("xyz"); Str ...

随机推荐

  1. gitlab升级和迁移

    由于近期公司gitlab服务器老是卡顿和出现其他问题,然后也很久没有升级过了,现在版本还是8.10.5,而官网最新版本已经是11.2了.另一个原因是gitlab所在的这台服务器快到期了,想换一台配置更 ...

  2. Xss Bypass备忘录

    Xss Bypass备忘录 技术要发展,免不了风波. 也许这些攻攻防防会更好的促进技术的发展也说不定 就让这一次次的爆破换来将来更精练的技术的无比的宁静吧 我们静观其变吧! 缅怀当初那份最纯真Hack ...

  3. DUMP2 企业级电商项目

    正常设计数据库表,按照数据流向. ~~闭环核心业务 [1用户]登录 =>浏览[2分类]+浏览[3商品]=>加入[4购物车]=>结算[5订单]+[6收货地址]=>[7支付] [购 ...

  4. SQLServer数据库文件由高版本向低版本转换

    这个只能用2012的生成脚本功能,在高级里面把脚本兼容设置成2008,并且选择生成架构和数据(默认是只有架构)拿这个脚本在2008上跑一次就行了 sqlserver 中使用sqlcmd 执行*.sql ...

  5. MySQL学习10 - 多表查询

    一.多表连接查询 1.交叉连接 2.内连接 3.外连接之左连接 4.外连接之右连接 5.全外连接 二.符合条件连接查询 三.子查询 1.带in关键字的子查询 2.带比较运算符的子查询 3.带EXIST ...

  6. Jumpserver(堡垒机)的安装与应用

    官网:http://docs.jumpserver.org/zh/docs/introduce.html 作者:邓聪聪 环境 系统: CentOS 7.6 IP: 172.16.16.2 关闭 sel ...

  7. 用Python进行SQLite数据库操作

    简单的介绍 SQLite数据库是一款非常小巧的嵌入式开源数据库软件,也就是说没有独立的维护进程,所有的维护都来自于程序本身.它是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经 ...

  8. LabVIEW--使用云端编译器编译多个vi

    使用ni 云服务器编译vi 详细请看链接: https://users.niwsc.com/compilecloud/#/ http://www.ni.com/white-paper/52328/en ...

  9. ASP.NET Core之中间件

    本文翻译自:http://www.tutorialsteacher.com/core/aspnet-core-middleware 基本概念 ASP.NET Core引入了中间件的概念,中间件是在AS ...

  10. Python-Django 模型层-单表查询

    单表操作 -增加,删,改:两种方式:queryset对象的方法,book对象的方法 -改:需要用save() -get()方法:查询的数据有且只有一条,如果多,少,都抛异常 单表查询 -<1&g ...