哈希表与哈希集合基本知识
哈希表
哈希表又叫作散列表,有键值对,常用于统计词频或其他mapping关系。
数组其实也属于一种哈希表。其索引就相当于key,该位置存储的值就是value。
创建过程:key→哈希函数→内存地址→key | value 对应的内存地址
哈希碰撞:两个不同的key通过同一个hash函数得到相同的内存地址。
解决:
- 拉链法(Seperate Chaining),又叫 Open Hashing:在冲突的元素用链表的方式指向下一个元素(较常用)
- 线性探测法(Linear Probing),又叫Open Addressing, Close Hashing:一定要保证tableSize大于dataSize。当遇到冲突时,向后寻找空位填入元素。
复杂度分析:
- 哈希表没有访问这个概念
- 搜索:对key搜索是否存在该key。O(1),如果出现哈希碰撞:O(k),k为碰撞元素的个数(拉链法)。
- 插入:通过key插入value值,O(1)
- 删除:通过key删除value,O(1)
空间复杂度非常高
哈希集合
特征:无序,不重复
作用:检查某元素是否存在;重复元素
链表集合和树集合很少用到。
过程:元素通过哈希函数转换为哈希值,在哈希表对应位置里查找有无元素。
有:对比是否相等。相等:更新。不相等:哈希冲突。
无:直接存
- 访问:不适用
- 搜索:无哈希冲突:O(1);有哈希冲突:O(k)
- 插入:无哈希冲突:O(1);有哈希冲突:O(k)
- 删除:无哈希冲突:O(1);有哈希冲突:O(k)
Python 中字典和集合的区别
参见@及时行樂_的详细整理。
LC242 有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1: 输入: s = "anagram", t = "nagaram" 输出: true
示例 2: 输入: s = "rat", t = "car" 输出: false
说明: 你可以假设字符串只包含小写字母。
题目中限定小写字母很关键,暗示我们可以利用数组和ASCII码来轻松解决这道题。
- 先遍历一次
s,统计词频并记录到table - 然后遍历一次
t,将对应元素的频率减一 - 最后检查
table中是否有不为0的元素,有则说明不是异位词。
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
# 初始化哈希表
table = [0] * 26
for c in s:
table[ord(c) - ord("a")] += 1
for d in t:
table[ord(d) - ord("a")] -= 1
for i in table:
if i != 0:
return False
return True
LC349 两个数组的交集
给定两个数组,编写一个函数来计算它们的交集。
这题的思路非常简单明了,将两个数组分别用集合表示,然后计算交集即可。
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
return list(set(nums1) & set(nums2))
更多详细的Python 中的集合运算,请参见链接。
LC202 快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,
也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:
输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
初见本题容易找不到关键信息:无限循环,一旦发现就能明白,题目中的操作是会造成重复结果的,这样就显而易见用集合来解决这道题。
要取一个整数n的个位数字,就n % 10,要取十位,就n // 10,要取百位,就n // 100或者重复n // 10两次,以此类推。
class Solution:
def isHappy(self, n: int) -> bool:
record = set()
digits = []
while n not in record:
record.add(n)
# 取出 n 的每一位数
while n != 0:
digits.append(n % 10)
n //= 10
# 计算快乐数
num = 0
while len(digits) != 0:
num += digits.pop() ** 2
if num == 1:
return True
n = num
return False
本文介绍了哈希表和哈希集合的基本知识,包括它们的创建过程、哈希碰撞的解决方法以及复杂度分析。讨论了Python中字典和集合的区别,并分享了解决LC242、LC349和LC202等编程问题的思路,这些题目涉及有效字母异位词、两个数组的交集和快乐数的判断,利用哈希表和集合可以高效地解决问题。
1811

被折叠的 条评论
为什么被折叠?



