哈希表-刷题笔记

基础

数组就是一张哈希表,一般用哈希表判断一个元素是否出现集合里。
常见的哈希结构
unordered_set,unordered_map

242.有效的字母异位词

  1. 创建一个哈希数组record,用来记录26个字母出现的次数
  2. 遍历字符串s,统计该字符串中出现的次数
  3. 然后遍历字符串t,哈希数组record--
  4. 遍历record哈希数组,如果哈希数组都为0,说明两个字符串的字符相同,如果哈希数组不等于0,说明两个字符串不相同。

383.赎金信

  1. 创建哈希数组record[26]
  2. 遍历第一个字符串统计字符出现次数
  3. 遍历第二个字符串统计字符出现次数,record--,如果当前遍历中,哈希数组小于0,说明不能组成,return false

49. 字母异位词分组

  1. 思路:题目要求将相同字母异位词分组并返回,此时想到使用umordered_map<string,vector<string>> codeGroup,key表示每个字符串的哈希编码,value表示将相同的哈希编码存储到vector数组
  2. 创建unordered_map,遍历数组中每个字符串
  3. 将每个下标的字符串通过一个哈希数组vector count(26,0)记录每个字符串的编码,返回字符串的形式,因为map中的value类型是string
  4. 将字符串编码相同的放入codeGroup,codeGroup[code].push_back(s)
  5. 得到的map类型,创建一个vector数组,遍历map的value,放入vector数组并返回

438. 找到字符串中所有字母异位词

  1. 题目要求不仅找到异位词,而且找到起始索引,想到哈希表-异位词,起始索引-滑动窗口
  2. 本题得创建两个哈希数组,第一个哈希数组统计第一个字符串的出现次数
  3. 遍历第二个字符串,开始寻找第一个字符串的异位词,如果当前遍历的索引大于第一个字符串的长度,那么需要滑动窗口的左边界,如果小于的话,滑动窗口的右边界
  4. 判断两个哈希数组是否相等,如果相等放入结果集

349. 两个数组的交集

  1. 选择unordered_set数据结构,正好符合题目要求的元素不重复
  2. 第一个数组nums1转化为unordered_set
  3. 遍历第二数组nums2,如果在unordered_set中找到nums2的元素,就放入结果集
  4. 返回结果集

350. 两个数组的交集 II

  1. 不同于上题的是,题目要求不仅返回两个数组的交集,也返回出现的次数,想到unordered_map类型结构,key表示元素,value表示每个元素出现的次数
  2. 遍历第一个数组nums1,统计每个元素出现的次数
  3. 遍历第二个数组nums2,如果在map集合中找到nums2的元素,放入结果集
  4. map的次数减少
  5. 最后map的次数为0,从map中去除该元素
  6. 返回结果集

202. 快乐数

  1. 本题目在于计算每个数的位数的平方,适用于循环num%10(计算个位上的数),num/10(减少位数)
  2. 设置一个函数计算出一个数每个位置上数的平方并返回
  3. 定义一个元素不重复的集合unordered_set,如果返回的所有平方和sum==1,说明就是快乐数
  4. 如果能在set集合中找到sum,说明有重复,返回false,如果没有找到,就插入到集合set集合
  5. 将sum赋值给n,以便进行下次循环

1. 两数之和

  1. 题目要求不仅找出两个数还要返回下标,想到unordered_map,key存元素,value存下标
  2. 遍历数组nums,如果map中存在tagrget-nums[i]的元素,返回数组下标,
  3. 没有找到的话,就添加到map中

第454题.四数相加II

  1. 题目要求不去重,创建unordered_map,key存放a和b两数之和,value放a和b两数之和出现的次数
  2. 遍历前a,b数组,统计出a+b两数之和以及出现的次数,
  3. 定义count,统计a+b+c+d的出现次数
  4. 遍历c,d数组,如果在map中找到0-(c+d)的元素,count++,count加的是map的value,也就是符合四元组的个数
  5. 返回count

15. 三数之和

  1. 题目要求不重复的三元组,需要去重,一般的哈希数组计算复杂度大,采用双指针的方法
  2. 双指针之前,先将数组进行排序,默认从小到大
  3. for循环遍历数组,i=0,表示第一个指针,left和right指针表示移动的双指针,left=i+1,right=nums.size()-1,剪枝操作,如果排序之后的数组,第一个元素大于0,之后的元素就不符合条件,直接返回
  4. 对a去重,如果nums[i]==nums[i-1],比较的是i的前一位,否则会漏掉-1,-1,2,这种情况
  5. 如果三个指针下标的元素大于0,说明right–,如果三个指针下标的元素小于0,说明left++
  6. 另一种就是三数之和等于和,将对应的数组下标存入结果集,再对b,c进行去重
  7. 对b,c去重,如果nums[right]==nums[right-1],right–,如果nums[left]==nums[left+1],left++,去重之后,左右两指针开始紧缩移动

第18题. 四数之和

  1. 思路与三数之和类似,就是多了一层for循环,第一个for循环,i=0,表示第一个指针,第二个for循环,k=i+1,表示第二个指针,第三个指针是left=k+1,第四个指针是right=nums.size()-1
  2. 对四个数的去重也有细微的差别,剪枝的时候直接break,跳出本层循环,不能直接return
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值