哈希表特点
常见的三种哈希结构:
1、数组:操作简单,方便快捷,但不适于进行一些更复杂的操作。
注:适用于用set
或map
的情景:(1)当数组大小受限;(2)数组空间足够,但存储键值稀疏;(3)Key值为负数或非正整数。
2、set(集合):仅含有Key,相当于是Value=1的哈希表。常用于判定某一元素是否存在。
3、map(映射):Key-Value形式,常用于计数、存储原始数组的下标等,重点是明确要赋予Value的含义。
(1)数组的定义
(2)Set的三种定义
对于要求有序的保证Key有序,使用set
,不要求保证Key有序使用unordered_set
(该方式的读写效率最高),对于要求含有重复Key的使用multiset
。
(3)Map的三种定义
对于要求有序的保证Key有序,使用map
,不要求保证Key有序使用unordered_map
(该方式的读写效率最高),对于要求含有重复Key的使用multimap
。
1、数组作为哈希表的题
67、【哈希表】leetcode——242. 有效的字母异位词(C++版本)
本题可利用都为小写字母的条件,根据ASCII码的特点,将每个字符中的数都减去a
,映射到0-25当中,设置一个常量级空间大小的数组作为哈希表。
383. 赎金信
思路与242. 有效的字母异位词相同,找到哈希表中可以字母可以拼凑出另一个字符串的字母即可,也利用小写字母的条件,映射到0-25当中。
2、Set作为哈希表的题
68、【哈希表】leetcode——349. 两个数组的交集(C++版本)
目标是寻找两个数组中的去重交集,因此只需要看有无出现相同元素即可,因键值可能会很稀疏,采用unordered_set
作为哈希表即可。
69、【哈希表】leetcode——202. 快乐数(C++版本)
本题的关键是出现无限循环数和满足相加为1,对于出现无限循环数条件,相当于是判定是否有再次出现该数,用unordered_set
做记录即可。
3、Map作为哈希表的题
(1)答案唯一,不需考虑去重:
70、【哈希表】leetcode——1. 两数之和(C++版本)
要求返回满足相加为target
的两个数的下标值,因此需要用map
形式存储下标,其中数组中的数作为Key
,下标作为Value
。
(2)允许交集中有重复元素,不需考虑去重:
71、【哈希表】leetcode——350. 两个数组的交集 II(C++版本)
因交集不去重,可存在重复元素,便将对应元素为Key
,Value
作为对应元素出现的次数。
(3)四个独立数组,不需考虑去重:
72、【哈希表】leetcode——454. 四数相加 II(C++版本)
采用两两相加组成新集合的方式,将四个集合,组合成两个集合,这个题便变为求两集合之和为0。让nums1[i] + nums2[j]
构成一个集合,映射成一个Hash表,Key为nums1[i]+nums2[j]
,Value为该值出现的次数。让nums3[k] + nums4[l]
构成另一个集合。符合目标条件的值,变为集合中数值等于0-(nums1[i]+nums2[j])
的值。每找到一次满足该值情况,就将集合1中符合该情况的次数相加。
(4)需考虑去重:
均采用先排序,再双指针的方式进行处理
73、【哈希表】leetcode——15. 三数之和(C++版本)
采用排序+双指针的方式,重点是剪枝条件和去重条件。
74、【哈希表】leetcode——18. 四数之和(C++版本)
思路与三数之和相同,区别在于多一层for循环和剪枝与去重条件进行稍微调整。