1.1哈希表基础知识
哈希表(Hash Table),也称为散列表,是一种通过哈希函数将键(Key)映射到表中一个位置以便快速访问记录的数据结构。它提供了非常快速的数据插入和查找能力。下面是哈希表的一些基本知识:
-
哈希表(Hash Table):又称散列表,是除顺序存储结构、链式存储结构和索引表存储结构之外的又一种存储结构。
-
哈希函数(Hash Function):哈希函数是一个算法,它接受一个键作为输入,并返回一个整数,这个整数通常用来在数组中索引数据。一个好的哈希函数应该能够将键均匀地分布在整个表中,以减少冲突。
-
键值对(Key-Value Pairs):哈希表存储数据的方式是键值对。每个键通过哈希函数映射到哈希表的一个位置,然后在这个位置上存储对应的值。
-
哈希冲突(Hash Collision):是指不同的键(Key)通过哈希函数映射到哈希表(Hash Table)的同一个位置。这是在哈希表中不可避免的现象,因为哈希函数将无限的键空间映射到有限的表空间。处理哈希冲突是设计哈希表时的关键考虑因素。
-
哈希碰撞(Hash Collision):与哈希冲突(Hash Collision)在概念上是相同的,都是指不同的键通过哈希函数映射到哈希表的同一个位置的情况。在哈希表的上下文中,这两个术语通常可以互换使用,都描述了同一个问题。
哈希碰撞是哈希表设计中必须处理的问题,因为理论上,如果哈希函数的输出范围有限,而输入(即键)的数量无限,那么不同的输入必然会映射到相同的输出位置。
-
哈希碰撞解决办法:
-
①链地址法 :在这种方法中,哈希表的每个槽位(Slot)都关联一个链(LinkedList)。当两个键映射到同一个位置时,它们会被添加到该位置的链表中。插入、查找和删除操作需要遍历链表,因此性能取决于链表的长度。
- ②开放寻址法:当发生冲突时,使用一种探查(Probing)方法在表中寻找下一个空闲位置。常见的探查方法包括:线性探查(Linear Probing):顺序检查下一个槽位,直到找到空位。二次探查(Quadratic Probing):使用二次方程来确定下一个槽位。双重散列(Double Hashing):使用第二个哈希函数来确定下一个槽位。
2.1有效的字母异位词
2.1.1相关理论
通常指的是两个字符串,它们包含相同的字符,并且每个字符出现的次数也相同,只是字符的排列顺序不同。要判断两个字符串是否是有效的字母异位词,可以采用以下几种方法:
-
排序比较:将两个字符串的字符按照相同的顺序排序,如果排序后的字符串相等,则它们是有效的字母异位词。
-
计数比较:创建一个计数器(例如使用数组或哈希表),统计每个字符串中每个字符出现的次数。然后比较两个计数器是否相等。
-
ASCII值比较:将每个字符串的字符转换为ASCII值,然后将相同位置的字符的ASCII值相加。如果两个字符串是有效的字母异位词,那么这两个总和应该是相等的。
-
位运算:对于每个字符,使用位运算来标记它在字符串中出现的位置。例如,如果字符 'a' 在字符串中出现,就在一个整数中将对应 'a' 的位设置为1。如果两个字符串是有效的字母异位词,那么这两个整数应该是相等的。
-
使用标准库函数:在某些编程语言中,有现成的库函数可以直接用来比较两个字符串是否是字母异位词。
2.1.2相关练习
LeetCode242题 “有效的字母异位词”(Valid Anagram)
要求判断两个字符串是否是有效的字母异位词。
LeetCode350 “两个数组的交集 II”(Intersection of Two Arrays II)【加分版】
题目要求是在给定两个数组,编写一个函数来计算它们的交集的平方。
3.1两个数组的交集
3.1.1相关理论
-
集合(Set):在编程中,集合通常用来表示一组唯一的元素。
-
交集(Intersection):两个集合的交集是指既属于集合A又属于集合B的所有元素组成的集合。交集操作通常在集合上进行,结果也是一个集合。
-
数组(Array):数组是一种线性数据结构,它存储一系列相同类型的元素。数组中的元素可以重复。
-
数组的交集:如果将数组视为集合,那么它们的交集就是两个数组中都存在的元素。如果数组包含重复元素,那么在求交集时需要决定是否保留这些重复。
-
去重(De-duplication):在求交集之前或之后,可能需要对数组进行去重操作,以确保结果中不包含重复的元素。
-
计数(Counting):当数组中的元素可以重复时,求交集可能需要考虑每个元素在数组中出现的次数。可以使用哈希表来统计每个元素的出现次数。
3.1.2相关练习
LeetCode349题 “两个数组的交集”(Intersection of Two Arrays)
题目要求找出两个数组的交集,并返回结果数组。结果中的每个元素一定是唯一的,并且不需要考虑元素的顺序。
4.1 (9.9)练习
LeetCode202 “快乐数”
编写一个算法来判断一个数 n
是否是快乐数。
一个「快乐数」定义为:
- 对于一个正整数,重复替换这个数,将被替换为它每个位置上的数字的平方和。
- 经过一系列这样的操作以后,这个数最终变为 1(一个特殊的情况,当这个数本身就是 1 时,不需要进行任何操作)。
- 如果这个数成为 0,那么它不会变成 1,因此不被认为是一个快乐数。
为了解决这个问题,我们可以采用快慢指针的方法,或者使用回溯法来检测循环。
LeetCode1 “两数之和”
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
LeetCode454 “四数相加 II”
给定四个整数数组 nums1
、nums2
、nums3
和 nums4
,计算有多少个元组 (i, j, k, l)
满足 nums1[i] + nums2[j] + nums3[k] + nums4[l] = 0
。