Leetcode数据结构学习day1——哈希表

一、概念

哈希表(Hash Table),数据结构,用于存储和检索键值对(Key-Value pairs)。

包含:

key

键通过哈希函数转换成“值”的索引

哈希函数

Hash(key)

中介

value

与键配对

哈希表的核心思想是使用哈希函数转换为索引,然后将值存储在对应索引位置的存储桶中。

通常基于数组实现的,通过数组的下标来访问存储桶。

二、优点:

高效存储(插入)和查找、空间效率高、可用表来存储计算好的结果(缓存)、当字典、数据库检索

三、哈希函数:

“魔术师”,特殊的魔法规则:

将任意大小的输入(比如一段文本、一个数字或者一个对象)转化成一个固定长度的输出,称为哈希值。

哈希函数输出范围固定。

哈希函数特性:

一致性:同输入同输出。

唯一性:不同输入应该不同输出。

高效性:快。

四、常见的哈希函数方法

1.直接地址法(Direct Addressing):适用键的范围较小且已知,索引位置即为键的值。要求:键的范围较小,否则会导致内存浪费。

2.除留余数法(Division Method):键除以一个固定的数(通常是哈希表的大小),取余数作为哈希值。例如,如果哈希表的大小是10,键为21,则哈希值为21除以10的余数1。

3.乘法哈希法(Multiplication Method):将键乘以一个介于0和1之间的常数,然后乘积的小数部分乘以哈希表的大小,最后取整数部分作为哈希值。好处:更好地分散键的分布,减少哈希冲突的可能性。

4.布尔哈希法(Boolean Hashing):适用于位向量的哈希函数方法。对于给定的键,布尔哈希函数将键的每个位进行逻辑运算,例如按位异或或按位与,然后将结果作为哈希值。

5.加法哈希法(Additive Hashing):适用于字符串类型的键。它将字符串中每个字符的 ASCII 值相加,然后取总和的余数作为哈希值。简单应用:行;较长的字符串:可能不太行,有较高的哈希冲突。

五、问题:

哈希冲突(Hash Collision)

不同的经过哈希函数计算后得到相同的哈希值,GG了。

解决方法:
1.链表法(Chaining)

基于以下思想:在哈希表的每个位置上,我们不仅存储一个键值对,也存储一个链表(或其他数据结构),用于存储具有相同哈希值的键值对。

当发生哈希冲突时,将它们添加到同一个位置上的链表中(见图1,好理解),这个位置上的链表对应相同哈希值的键值对集合

查找时,先通过哈希函数找到相应的位置,然后遍历该位置上的链表,直到找到目标键值对或遍历完整个链表。

图1 链表法示意图

2.开放地址法(Open Addressing)

在哈希表的每个位置上,存储一个键值对。当发生哈希冲突时,可以通过探测(Probing)方法,在哈希表中寻找下一个可用的位置来存储。常见的探测方法包括线性探测(i+1)、二次探测(i+2^1或2或3)和双重哈希等。当插入或查找时,如果发现目标位置已经被占用,则继续探测下一个位置,直到找到空闲位置或者遍历完整个哈希表。

六、python代码:

哈希表在python==字典

#字典创建方式

keys = ["key1", "key2", "key1"]

values = ["value1", "value2", "value3"]

dictionary = dict(zip(keys, values))

print(dictionary)

七、leedcode解题:

217. 存在重复元素

idea:利用python字典的键不能相同的特点:相同,后一个值会覆盖前一个,导致字典长度与原列表长度不一致。

class Solution:

    def containsDuplicate(self, nums: List[int]) -> bool:

        values=[ _ for _ in range(len(nums))]

        dic=dict(zip(nums,values))

        if len(dic) != len(nums):

            return True

        else:

            return False

参考资料:

  1. LeetCode 算法笔记
  2. HASH TABLE :: CHAINING (Java, C++) | Algorithms and Data Structures

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值