文章持续更新,微信搜索「代码随想录」第一时间围观,本文GitHub:https://github.com/youngyangyang04/TechCPP 已经收录,里面有更多干货等着你,欢迎Star!

如果对哈希表还不了解的话,可以先看这篇 关于哈希表,你该了解这些!

接下来我们要明确 哈希法可以用来解决什么问题, 当我们需要判断一个元素是否出现过的时候,就要考虑哈希表。

哈希法通常使用如下三种数据结构 :

  • 数组
  • set
  • map

接下来我们分别看一下三个容器在哈希法中的应用。

数组在哈希法中的应用

leetcode 383.赎金信

这道题题意很清晰,就是用判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成,但是这里需要注意两点1。

  • 第一点“为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思” 这里说明杂志里面的字母不可重复使用。

  • 第二点 “你可以假设两个字符串均只含有小写字母。” 说明只有小写字母,这一点很重要。

因为题目所只有小写字母,那我们可以采用空间换区时间的哈希策略, 用一个长度为26的数组还记录magazine里字母出现的次数,然后再用ransomNote去验证这个数组是否包含了ransomNote所需要的所有字母。

题解:https://github.com/youngyangyang04/leetcode/blob/master/problems/0383.赎金信.md

leetcode 575.分糖果

糖果的种类是可妹妹先来,所以思路先求出一共有多少种类型的糖果。

需要注意: 数组中数字的大小也就是糖果的种类取值范围在[负十万和 正十万之间], 依然可以定义一个数组,通过哈希法求出有多少类型的糖果。

那么糖果种类可以是负数 怎么办呢,可以把 定一个 20万大小的数组 ,就可以把糖果的全部类型映射到数组的下表了。

通过哈希法,可以求出了糖果的类型数量,如果糖果种类大于糖果总数的一半了,返回 糖果数量的一半就好,因为妹妹已经得到种类最多的糖果了,否则,就是返回 糖果的种类。

题解:https://github.com/youngyangyang04/leetcode/blob/master/problems/0575.分糖果.md

set在哈希法中的应用

leetcode 349.两个数组的交集

这道题目,主要要学会使用一种哈希数据结构,unordered_set,这个数据结构可以解决很多类似的问题。

注意题目特意说明:输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序。

这道题用暴力的解法时间复杂度是O(n^2),这种解法面试官一定不会满意,那我们看看使用哈希法进一步优化。

那么可以发现,貌似用数组做哈希表可以解决这道题目,把nums1的元素,映射到哈希数组的下表上,然后在遍历nums2的时候,判断是否出现过就可以了。

但是要注意,使用数据来做哈希的题目,都限制了数值的大小,例如只有小写字母,或者数值大小在[0- 10000] 之内等等。 而这道题目没有限制数值的大小,就无法使用数组来做哈希表了。

例如说:如果我的输入样例是这样的, 难道要定义一个2亿大小的数组来做哈希表么, 不同的语言对数组定义的大小都是有限制的, 即使有的语言可以定义这么大的数组,那也是对内存空间造成了非常大的浪费。

此时我们就要使用另一种结构体了,set ,关于set,C++ 给我们提供了如下三种可用的数据结构。

  • std::set
  • std::multiset
  • std::unordered_set

std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希表, 使用unordered_set 读写效率是最高的,我们并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。

题解:https://github.com/youngyangyang04/leetcode/blob/master/problems/0349.两个数组的交集.md

leetcode 202.快乐数

这道题目重点是,题目中说了会 无限循环, 那么也就是说 求和的过程中,sum会重复出现,这对我们解题很重要,这样我们就可以使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。

还有就是求和的过程,如果对取数值各个位上的单数操作不熟悉的话,做这道题也会比较艰难。

题解:https://github.com/youngyangyang04/leetcode/blob/master/problems/0202.快乐数.md

map在哈希法中的应用

leetcode 1.两数之和

很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2) 。
我们来看一下使用数组和set来做哈希法的局限。

  • 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
  • set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下表位置,因为我们要返回x 和 y的下表。所以set 也不能用。

此时我们就要选择另一种数据结构 map ,map是一种key value的存储结构,我们可以用key保存数值,用value在保存数值所在的下表。
这道题目是map在哈希法中的经典应用。

题解:https://github.com/youngyangyang04/leetcode/blob/master/problems/0001.两数之和.md

leetcode 454.四数相加II

本题使用哈希表映射的方法。

那么为什么18. 四数之和,0015.三数之和不适用哈希表映射的方法呢,感觉上 这道题目都是四个数之和都可以用哈希,三数之和怎么就用不了哈希呢。

因为题目15.三数之和和18. 四数之和,使用哈希的方法在不超时的情况下做到对结果去重很困难。

而这道题目 相当于说 不用考虑重复元素,是四个独立的数组,所以相对于题目18. 四数之和,0015.三数之和,还是简单了不少。

题解:https://github.com/youngyangyang04/leetcode/blob/master/problems/0454.四数相加II.md

三数之和&四数之和

三数之和 四数之和的问题,用哈希法也可以解决,但是最好使用双指针法,因为使用哈希法的话去重逻辑有很多细节需要注意,很难快速写出没有bug的代码。

所以几数之和的问题,我将单独写一篇文章来介绍。

  • 题解:https://github.com/youngyangyang04/leetcode/blob/master/problems/0015.三数之和.md
  • 题解:https://github.com/youngyangyang04/leetcode/blob/master/problems/0015.三数之和.md

总结

哈希法的本质是空间换时间,通过数组,set和map将数据已经预处理,从而通过O(1)的时间复杂度快速判断出元素是否出现某个集合中。

数组的限制是数组的大小,当我们的哈希值超过了数组大小的时候,就无法映射到数据下表上。

进而采用set,set的限制是只能存放单一key,不能记录更多的数据。

进而考虑map,map通过<key, value> 的存储结构,允许我们更加灵活的存储哈希值和对应的数值。

以上六道题目都非常具有代表性,大家可以按循序做一下,相信会对哈希法有所感悟。

更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。

一文学会哈希法解题,助你事半功倍(leetcode哈希表面试高频题目总结)相关推荐

  1. c语言全排列算法_一文学会回溯搜索算法解题技巧

    点击上方蓝字设为星标 下面开始今天的学习- 本文向大家介绍了回溯算法的基础知识,以帮助大家更好地理解回溯算法. 回溯搜索算法简介 维基百科中关于回溯算法的介绍是: 回溯算法(backtracking) ...

  2. (干货).NET开发丰富的公共类库助你事半功倍(供下载免费使用)

    (干货).NET开发丰富的公共类库助你事半功倍(供下载免费使用) Good company on the road is the shortest cut.(行路有良伴就是捷径).作为开发人员(苦逼) ...

  3. [英雄星球六月集训LeetCode解题日报] 第七日 哈希表

    [英雄星球六月集训LeetCode解题日报] 第七日 哈希表 一. 442. 数组中重复的数据 1. 题目描述 2. 思路分析 3. 代码实现 二. 2068. 检查两个字符串是否几乎相等 1. 题目 ...

  4. 88道BAT Java面试题 助你跳槽BAT,轻松应对面试官的灵魂拷问

    88道BAT Java面试题 助你跳槽BAT,轻松应对面试官的灵魂拷问 前言: 备战金九银十逃脱不了面试官的灵魂拷问,笔者整理了88道Java面试,由于面试题太多文章没有包含答案,需要领取这些面试题答 ...

  5. 【解题报告】《LeetCode零基础指南》(第三讲) 循环

    ☘前言☘ 今天是九日集训第二天,我会记录一下学习内容和题解,争当课代表0.0. 注意!!!!题解的解法一是今天要掌握的解法,解法2是学有余力再研究,涉及到后面知识点0.0 链接:<LeetCod ...

  6. 高效 遍历 算法_一文学会回溯算法解题技巧

    (给算法爱好者加星标,修炼编程内功) 来源:码海 前言 上文我们学习了深度优先搜索和广度优先搜索,相信大家对这两者的算法有了比较清楚的认识,值得一提的,深度优先算法用到了回溯的算法思想,这个算法虽然相 ...

  7. 一文学会回溯算法解题技巧

    前言 上文我们学习了深度优先搜索和广度优先搜索,相信大家对这两者的算法有了比较清楚的认识,值得一提的,深度优先算法用到了回溯的算法思想,这个算法虽然相对比较简单,但很重要,在生产上广泛用在正则表达式, ...

  8. Leetcode 171. Excel表列序号 解题思路及C++实现

    解题思路: 26进制转10进制.没啥可说的了. class Solution { public:int get_26(int n){int res = 1;while(n > 0){res *= ...

  9. Leetcode 168. Excel表列名称 解题思路及C++实现

    解题思路: 相当于实现了一个10进制转26进制. 要注意减 1 . class Solution { public:string convertToTitle(int n) {char a[26] = ...

  10. Leetcode 347. 前K个高频元素 解题思路及C++实现

    方法一:最小堆 解题思路: 先使用一个unordered_map来遍历nums容器,得到每个元素对应的频数. 再使用最小堆,对unordered_map中的频数进行遍历,得到k个最大的频数对应的< ...

最新文章

  1. R语言dplyr包获取dataframe分组聚合汇总统计值实战(group_by() and summarize() ):均值、中位数、分位数、IQR、MAD、count、unique
  2. 人工智能和自主系统在美军联合职能中的应用
  3. 索赔 100 万!只是因为一个开源插件?
  4. Python3压缩和解压缩实现
  5. python怎么画圆并改变线条颜色_基于logi的matplotlib中线条颜色的改变
  6. 数据导出生成word附件使用POI的XWPFTemplate对象
  7. java声明和初始化数组_Java 中初始化数组
  8. hdu 1233 最小生成树
  9. 爬虫实战学习笔记_1 爬虫基础+HTTP原理
  10. 配置所需要的依赖_配置spring所需要的jar包
  11. Java案例:压缩与解压缩文件
  12. windows2008开机占用多少内存_如何提升电脑开机速度?
  13. 使用Redis进行搜索
  14. java quartz插件_JFinal Quartz 2.2.1插件
  15. java long转float_Java中为什么long能自动转换成float类型
  16. 2020年上半年我国互联网网络安全监测数据分析报告
  17. 2022年茶艺师(中级)证考试及茶艺师(中级)模拟考试题库
  18. WebRTC实时通信系列教程7 使用Socket.IO搭建信令服务器交换信息
  19. python爬取高校课程信息进行选课实战
  20. 和程序员薪酬差不多的工作

热门文章

  1. MVC的自定义动作过滤器(一)
  2. ArcGIS依据某一字段进行数据分层
  3. ThinkPad特有设计和特色软件
  4. 使用JIRA搭建企业问题跟踪系统.PART5(转)
  5. 写一条SQL,使它通过全表扫描方式的效率优于索引访问,分别给出各自的执行计划。...
  6. 【练习】Java实现的杨辉三角形控制台输出
  7. boostrap中模态框显示在阴影之下
  8. mbstring未安装
  9. SQL Server 数据库所有表增加同一列
  10. Kotlin 区间的一些小注意