基础
数组就是一张哈希表,一般用哈希表判断一个元素是否出现集合里。
常见的哈希结构
unordered_set,unordered_map
242.有效的字母异位词
- 创建一个哈希数组
record
,用来记录26个字母出现的次数 - 遍历字符串
s
,统计该字符串中出现的次数 - 然后遍历字符串
t
,哈希数组record--
- 遍历
record
哈希数组,如果哈希数组都为0,说明两个字符串的字符相同,如果哈希数组不等于0,说明两个字符串不相同。
383.赎金信
- 创建哈希数组
record[26]
- 遍历第一个字符串统计字符出现次数
- 遍历第二个字符串统计字符出现次数,
record--
,如果当前遍历中,哈希数组小于0,说明不能组成,return false
49. 字母异位词分组
- 思路:题目要求将相同字母异位词分组并返回,此时想到使用
umordered_map<string,vector<string>> codeGroup
,key表示每个字符串的哈希编码,value表示将相同的哈希编码存储到vector数组 - 创建unordered_map,遍历数组中每个字符串
- 将每个下标的字符串通过一个哈希数组
vector count(26,0)
记录每个字符串的编码,返回字符串的形式,因为map中的value类型是string - 将字符串编码相同的放入codeGroup,
codeGroup[code].push_back(s)
- 得到的map类型,创建一个vector数组,遍历map的value,放入vector数组并返回
438. 找到字符串中所有字母异位词
- 题目要求不仅找到异位词,而且找到起始索引,想到哈希表-异位词,起始索引-滑动窗口
- 本题得创建两个哈希数组,第一个哈希数组统计第一个字符串的出现次数
- 遍历第二个字符串,开始寻找第一个字符串的异位词,如果当前遍历的索引大于第一个字符串的长度,那么需要滑动窗口的左边界,如果小于的话,滑动窗口的右边界
- 判断两个哈希数组是否相等,如果相等放入结果集
349. 两个数组的交集
- 选择
unordered_set
数据结构,正好符合题目要求的元素不重复 - 第一个数组
nums1
转化为unordered_set
- 遍历第二数组
nums2
,如果在unordered_set
中找到nums2
的元素,就放入结果集 - 返回结果集
350. 两个数组的交集 II
- 不同于上题的是,题目要求不仅返回两个数组的交集,也返回出现的次数,想到unordered_map类型结构,key表示元素,value表示每个元素出现的次数
- 遍历第一个数组nums1,统计每个元素出现的次数
- 遍历第二个数组nums2,如果在map集合中找到nums2的元素,放入结果集
- map的次数减少
- 最后map的次数为0,从map中去除该元素
- 返回结果集
202. 快乐数
- 本题目在于计算每个数的位数的平方,适用于循环
num%10(计算个位上的数),num/10(减少位数)
- 设置一个函数计算出一个数每个位置上数的平方并返回
- 定义一个元素不重复的集合unordered_set,如果返回的所有平方和sum==1,说明就是快乐数
- 如果能在set集合中找到sum,说明有重复,返回false,如果没有找到,就插入到集合set集合
- 将sum赋值给n,以便进行下次循环
1. 两数之和
- 题目要求不仅找出两个数还要返回下标,想到unordered_map,key存元素,value存下标
- 遍历数组nums,如果map中存在tagrget-nums[i]的元素,返回数组下标,
- 没有找到的话,就添加到map中
第454题.四数相加II
- 题目要求不去重,创建unordered_map,key存放a和b两数之和,value放a和b两数之和出现的次数
- 遍历前a,b数组,统计出a+b两数之和以及出现的次数,
- 定义count,统计a+b+c+d的出现次数
- 遍历c,d数组,如果在map中找到0-(c+d)的元素,count++,count加的是map的value,也就是符合四元组的个数
- 返回count
15. 三数之和
- 题目要求不重复的三元组,需要去重,一般的哈希数组计算复杂度大,采用双指针的方法
- 双指针之前,先将数组进行排序,默认从小到大
- for循环遍历数组,i=0,表示第一个指针,left和right指针表示移动的双指针,left=i+1,right=nums.size()-1,剪枝操作,如果排序之后的数组,第一个元素大于0,之后的元素就不符合条件,直接返回
- 对a去重,如果nums[i]==nums[i-1],比较的是i的前一位,否则会漏掉-1,-1,2,这种情况
- 如果三个指针下标的元素大于0,说明right–,如果三个指针下标的元素小于0,说明left++
- 另一种就是三数之和等于和,将对应的数组下标存入结果集,再对b,c进行去重
- 对b,c去重,如果nums[right]==nums[right-1],right–,如果nums[left]==nums[left+1],left++,去重之后,左右两指针开始紧缩移动
第18题. 四数之和
- 思路与三数之和类似,就是多了一层for循环,第一个for循环,i=0,表示第一个指针,第二个for循环,k=i+1,表示第二个指针,第三个指针是left=k+1,第四个指针是right=nums.size()-1
- 对四个数的去重也有细微的差别,剪枝的时候直接break,跳出本层循环,不能直接return