LeetCode 706. 设计哈希映射(数组法,稀疏矩阵法,链地址法,开放定址法)

本文主要是介绍LeetCode 706. 设计哈希映射(数组法,稀疏矩阵法,链地址法,开放定址法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

思路:

参考:https://leetcode-cn.com/problems/design-hashmap/solution/706-she-ji-ha-xi-ying-she-by-jyj407-nzcz/

解法1:
因为数据不大,直接用数组保存每个值的映射。

class MyHashMap {
private:vector<int>cache;
public:/** Initialize your data structure here. */MyHashMap() {cache.resize(1000005,-1);}/** value will always be non-negative. */void put(int key, int value) {cache[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) {return cache[key];}/** Removes the mapping of the specified value key if this map contains a mapping for the key */void remove(int key) {cache[key] = -1;}
};

解法2:
二维稀疏矩阵,节省空间

class MyHashMap {
private:vector<vector<int>>data;int N = 1001;
public:/** Initialize your data structure here. */MyHashMap() {data.resize(N);}int getHashKey1(int x) {return x / N;}int getHashKey2(int x) {return x % N;}/** value will always be non-negative. */void put(int key, int value) {int hashKey1 = getHashKey1(key);int hashKey2 = getHashKey2(key);if(data[hashKey1].empty()) data[hashKey1].resize(N,-1);data[hashKey1][hashKey2] = 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) {int hashKey1 = getHashKey1(key);int hashKey2 = getHashKey2(key);if(data[hashKey1].empty()) return -1;return data[hashKey1][hashKey2];}/** Removes the mapping of the specified value key if this map contains a mapping for the key */void remove(int key) {int hashKey1 = getHashKey1(key);int hashKey2 = getHashKey2(key);if(data[hashKey1].size()) data[hashKey1][hashKey2] = -1;}
};

解法3:
构建哈希表,拉链法解决哈希冲突

struct MyListNode {int key,val;MyListNode* next;MyListNode(): key(-1),val(-1),next(nullptr){}MyListNode(int _key,int _val):key(_key),val(_val),next(nullptr){}
};
class MyHashMap {
private:vector<MyListNode*>data;int N = 1009;
public:MyHashMap() {data.resize(N,new MyListNode());}int getHashKey(int key) {return key % N;}void put(int key, int value) {int hashKey = getHashKey(key);MyListNode *head = data[hashKey];MyListNode *p = head;MyListNode *tail = p;while(p != nullptr) {if(p -> key == key) {p -> val = value;return;}tail = p;p = p -> next;}tail -> next = new MyListNode(key,value);}int get(int key) {int hashKey = getHashKey(key);MyListNode* head = data[hashKey];MyListNode* p = head;while(p != nullptr) {if(p -> key == key) {return p -> val;}p = p -> next;}return -1;}void remove(int key) {int hashKey = getHashKey(key);MyListNode* head = data[hashKey];MyListNode* prev = head;MyListNode* p = head -> next;while(p != nullptr) {if(p -> key == key) {prev -> next = p -> next;p -> next = nullptr;delete(p);return;}prev = p;p = p -> next;}}
};

解法4:
STL实现的双向链表,使用双向链表的原因是在已知迭代器(指针)的情况下可以做到O(1)删除。

class MyHashMap {
private:vector<list<pair<int,int>>>data;int N = 1009;
public:MyHashMap() {data.resize(N);}int getHashKey(int key) {return key % N;}list<pair<int,int>>::iterator find(int key) {int hashKey = getHashKey(key);auto& it = data[hashKey];for(auto iter = it.begin();iter != it.end();iter++) {if(iter -> first == key) {return iter;}}return it.end();}void put(int key, int value) {int hashKey = getHashKey(key);auto iter = find(key);if(iter != data[hashKey].end()) {iter -> second = value;return;}data[hashKey].push_back({key,value});}   int get(int key) {int hashKey = getHashKey(key);auto iter = find(key);if(iter != data[hashKey].end()) {return iter -> second;}return -1;}void remove(int key) {int hashKey = getHashKey(key);auto iter = find(key);if(iter != data[hashKey].end()) {data[hashKey].erase(iter);}}
};

解法5:
C++实现的双向链表

struct MyListNode {int key,val;MyListNode* next;MyListNode* prev;MyListNode():key(-1),val(-1),next(nullptr),prev(nullptr){}MyListNode(int _key,int _val):key(_key),val(_val),next(nullptr),prev(nullptr){}
};
class MyHashMap {
private:vector<MyListNode*>data;int N = 1009;
public:MyHashMap() {data.resize(N,new MyListNode());}int getHashKey(int key) {return key % N;}MyListNode* find(int key) {int hashKey = getHashKey(key);MyListNode* head = data[hashKey];while(head != nullptr) {if(head -> key == key) return head;head = head -> next;}return nullptr;}void del(MyListNode* p) {p -> prev -> next = p -> next;if(p -> next) p -> next -> prev = p -> prev;p -> next = p -> prev = nullptr;delete(p);}void put(int key, int value) {int hashKey = getHashKey(key);MyListNode* p = find(key);MyListNode* head = data[hashKey];if(p != nullptr) {p -> val = value;return;}MyListNode* newNode = new MyListNode(key,value);newNode -> next = head -> next;if(head -> next != nullptr) {head -> next -> prev = newNode;}head -> next = newNode;newNode -> prev = head;}int get(int key) {int hashKey = getHashKey(key);MyListNode* iter = find(key);if(iter != nullptr) {return iter -> val;}return -1;}void remove(int key) {int hashKey = getHashKey(key);  MyListNode* iter = find(key);if(iter != nullptr) {del(iter);}}
};

解法6:
开放定址,线性探测

class MyHashMap {
private:const static int N = 20005;vector<pair<int,int>>hashTable;
public:MyHashMap() {hashTable.resize(N,{-1,-1});}int getHashKey(int key) {int k = key % N;while(hashTable[k].first != key && hashTable[k].first != -1) {k = (k + 1) % N;}return k;}void put(int key, int value) {int k = getHashKey(key);hashTable[k] = {key,value};}int get(int key) {int k = getHashKey(key);return hashTable[k].second;}void remove(int key) {int k = getHashKey(key);if(hashTable[k].first != -1) {hashTable[k].first = -2;}}
};

这篇关于LeetCode 706. 设计哈希映射(数组法,稀疏矩阵法,链地址法,开放定址法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907162

相关文章

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

Kotlin Map映射转换问题小结

《KotlinMap映射转换问题小结》文章介绍了Kotlin集合转换的多种方法,包括map(一对一转换)、mapIndexed(带索引)、mapNotNull(过滤null)、mapKeys/map... 目录Kotlin 集合转换:map、mapIndexed、mapNotNull、mapKeys、map

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

Java继承映射的三种使用方法示例

《Java继承映射的三种使用方法示例》继承在Java中扮演着重要的角色,它允许我们创建一个类(子类),该类继承另一个类(父类)的所有属性和方法,:本文主要介绍Java继承映射的三种使用方法示例,需... 目录前言一、单表继承(Single Table Inheritance)1-1、原理1-2、使用方法1-

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

MyBatis设计SQL返回布尔值(Boolean)的常见方法

《MyBatis设计SQL返回布尔值(Boolean)的常见方法》这篇文章主要为大家详细介绍了MyBatis设计SQL返回布尔值(Boolean)的几种常见方法,文中的示例代码讲解详细,感兴趣的小伙伴... 目录方案一:使用COUNT查询存在性(推荐)方案二:条件表达式直接返回布尔方案三:存在性检查(EXI

Nginx Location映射规则总结归纳与最佳实践

《NginxLocation映射规则总结归纳与最佳实践》Nginx的location指令是配置请求路由的核心机制,其匹配规则直接影响请求的处理流程,下面给大家介绍NginxLocation映射规则... 目录一、Location匹配规则与优先级1. 匹配模式2. 优先级顺序3. 匹配示例二、Proxy_pa

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元