1.哈希表概念
通过键key和映射函数计算出来的值,把关键码值映射到表的某个区块中来访问
好处是加快查找的速度,时间复杂度为O(1)
坏处是内存空间占用大,空间使用效率不高
关键核心的问题是:哈希函数创建和哈希冲突的解决
2.哈希函数
将哈希表中元素的关键键值映射为元素存储位置的函数。
- 除留余数法 即%,取模运算
- 直接地址法 原有的值为某个线性函数值
- 平方取中法 先计算平方去除末尾的 2 位数,再取中间 3 位数作为哈希地址
- 基数转换法 关键字通过进制转话, md5,sha加密hash算法等
3.哈希冲突
不同输入值通过哈希函数转换会变成同一个哈希输出值
解决之道:
开放地址法
- 当前地址发生冲突了,就往后继续找空闲的位置
- 缺陷:当表中的元素越来越多时,线性探测法为了找到空闲位置需要遍历的长度就会越来越长,性能由O(1)逐渐达到O(n)
链地址法
将具有相同哈希地址的元素(或记录)存储在同一个线性链表中。
4.刷题提升
描述:给定两个数组 nums1
和 nums2
。
要求:返回两个数组的交集。可以不考虑输出结果的顺序。
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2,2]
from collections import Counter
def intersect(nums1, nums2):
# 计算两个数组中每个元素的出现次数
counter1 = Counter(nums1)
counter2 = Counter(nums2)
# 找出交集
intersection = counter1 & counter2
# 转化为列表并返回
return list(intersection.elements())
nums1 = [1,2,2,1]
nums2 = [2,2]
print(intersect(nums1, nums2)) # 输出:[2, 2]