LeetCode-705. 设计哈希集合【设计 数组 哈希表 链表 哈希函数】

2024-04-15 05:20

本文主要是介绍LeetCode-705. 设计哈希集合【设计 数组 哈希表 链表 哈希函数】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LeetCode-705. 设计哈希集合【设计 数组 哈希表 链表 哈希函数】

  • 题目描述:
  • 解题思路一:超大数组
  • 解题思路二:拉链法
  • 解题思路三:定长拉链数组

题目描述:

不使用任何内建的哈希表库设计一个哈希集合(HashSet)。

实现 MyHashSet 类:

void add(key) 向哈希集合中插入值 key 。
bool contains(key) 返回哈希集合中是否存在这个值 key 。
void remove(key) 将给定值 key 从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。

示例:

输入:
[“MyHashSet”, “add”, “add”, “contains”, “contains”, “add”, “contains”, “remove”, “contains”]
[[], [1], [2], [1], [3], [2], [2], [2], [2]]
输出:
[null, null, null, true, false, null, true, null, false]

解释:
MyHashSet myHashSet = new MyHashSet();
myHashSet.add(1); // set = [1]
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(1); // 返回 True
myHashSet.contains(3); // 返回 False ,(未找到)
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(2); // 返回 True
myHashSet.remove(2); // set = [1]
myHashSet.contains(2); // 返回 False ,(已移除)

提示:

0 <= key <= 106
最多调用 104 次 add、remove 和 contains

解题思路一:超大数组

class MyHashSet:def __init__(self):self.set = [False] * 1000001def add(self, key: int) -> None:self.set[key] = Truedef remove(self, key: int) -> None:self.set[key] = Falsedef contains(self, key: int) -> bool:return self.set[key]# Your MyHashSet object will be instantiated and called as such:
# obj = MyHashSet()
# obj.add(key)
# obj.remove(key)
# param_3 = obj.contains(key)

时间复杂度:O(1)
空间复杂度:O(数据范围)

解题思路二:拉链法

在这里插入图片描述
不定长的拉链数组是说拉链会根据分桶中的 key 动态增长,更类似于真正的链表。

分桶数一般取质数,这是因为经验上来说,质数个的分桶能让数据更加分散到各个桶中。

优点:节省内存,不用预知数据范围;
缺点:在链表中查找元素需要遍历。

class MyHashSet:def __init__(self):self.buckets = 1009self.table = [[] for _ in range(self.buckets)]def hash(self, key):return key % self.bucketsdef add(self, key: int) -> None:hashkey = self.hash(key)if key in self.table[hashkey]:returnself.table[hashkey].append(key)def remove(self, key: int) -> None:hashkey = self.hash(key)if key not in self.table[hashkey]:returnself.table[hashkey].remove(key)def contains(self, key: int) -> bool:hashkey = self.hash(key)return key in self.table[hashkey]

时间复杂度:O(N/b) N 是元素个数,b 是桶数。
空间复杂度:O(N)

解题思路三:定长拉链数组

这个方法本质上就是把 HashSet 设计成一个 M∗N 的二维数组。第一个维度用于计算 hash 分桶,第二个维度寻找 key 存放具体的位置。用了一个优化:第二个维度的数组只有当需要构建时才会产生,这样可以节省内存。

优点:两个维度都可以直接计算出来,查找和删除只用两次访问内存。
缺点:需要预知数据范围,用于设计第二个维度的数组大小。

class MyHashSet:def __init__(self):self.buckets = 1000self.itemsPerBucket = 1001self.table = [[] for _ in range(self.buckets)]def hash(self, key):return key % self.bucketsdef pos(self, key):return key // self.bucketsdef add(self, key):hashkey = self.hash(key)if not self.table[hashkey]:self.table[hashkey] = [0] * self.itemsPerBucketself.table[hashkey][self.pos(key)] = 1def remove(self, key):hashkey = self.hash(key)if self.table[hashkey]:self.table[hashkey][self.pos(key)] = 0def contains(self, key):hashkey = self.hash(key)return (self.table[hashkey] != []) and (self.table[hashkey][self.pos(key)] == 1)

时间复杂度:O(1)
空间复杂度:O(数据范围)

这篇关于LeetCode-705. 设计哈希集合【设计 数组 哈希表 链表 哈希函数】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

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

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

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

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

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

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与

java中BigDecimal里面的subtract函数介绍及实现方法

《java中BigDecimal里面的subtract函数介绍及实现方法》在Java中实现减法操作需要根据数据类型选择不同方法,主要分为数值型减法和字符串减法两种场景,本文给大家介绍java中BigD... 目录Java中BigDecimal里面的subtract函数的意思?一、数值型减法(高精度计算)1.

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一