一文学会哈希法解题,助你事半功倍(leetcode哈希表面试高频题目总结)
文章持续更新,微信搜索「代码随想录」第一时间围观,本文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哈希表面试高频题目总结)相关推荐
- c语言全排列算法_一文学会回溯搜索算法解题技巧
点击上方蓝字设为星标 下面开始今天的学习- 本文向大家介绍了回溯算法的基础知识,以帮助大家更好地理解回溯算法. 回溯搜索算法简介 维基百科中关于回溯算法的介绍是: 回溯算法(backtracking) ...
- (干货).NET开发丰富的公共类库助你事半功倍(供下载免费使用)
(干货).NET开发丰富的公共类库助你事半功倍(供下载免费使用) Good company on the road is the shortest cut.(行路有良伴就是捷径).作为开发人员(苦逼) ...
- [英雄星球六月集训LeetCode解题日报] 第七日 哈希表
[英雄星球六月集训LeetCode解题日报] 第七日 哈希表 一. 442. 数组中重复的数据 1. 题目描述 2. 思路分析 3. 代码实现 二. 2068. 检查两个字符串是否几乎相等 1. 题目 ...
- 88道BAT Java面试题 助你跳槽BAT,轻松应对面试官的灵魂拷问
88道BAT Java面试题 助你跳槽BAT,轻松应对面试官的灵魂拷问 前言: 备战金九银十逃脱不了面试官的灵魂拷问,笔者整理了88道Java面试,由于面试题太多文章没有包含答案,需要领取这些面试题答 ...
- 【解题报告】《LeetCode零基础指南》(第三讲) 循环
☘前言☘ 今天是九日集训第二天,我会记录一下学习内容和题解,争当课代表0.0. 注意!!!!题解的解法一是今天要掌握的解法,解法2是学有余力再研究,涉及到后面知识点0.0 链接:<LeetCod ...
- 高效 遍历 算法_一文学会回溯算法解题技巧
(给算法爱好者加星标,修炼编程内功) 来源:码海 前言 上文我们学习了深度优先搜索和广度优先搜索,相信大家对这两者的算法有了比较清楚的认识,值得一提的,深度优先算法用到了回溯的算法思想,这个算法虽然相 ...
- 一文学会回溯算法解题技巧
前言 上文我们学习了深度优先搜索和广度优先搜索,相信大家对这两者的算法有了比较清楚的认识,值得一提的,深度优先算法用到了回溯的算法思想,这个算法虽然相对比较简单,但很重要,在生产上广泛用在正则表达式, ...
- Leetcode 171. Excel表列序号 解题思路及C++实现
解题思路: 26进制转10进制.没啥可说的了. class Solution { public:int get_26(int n){int res = 1;while(n > 0){res *= ...
- Leetcode 168. Excel表列名称 解题思路及C++实现
解题思路: 相当于实现了一个10进制转26进制. 要注意减 1 . class Solution { public:string convertToTitle(int n) {char a[26] = ...
- Leetcode 347. 前K个高频元素 解题思路及C++实现
方法一:最小堆 解题思路: 先使用一个unordered_map来遍历nums容器,得到每个元素对应的频数. 再使用最小堆,对unordered_map中的频数进行遍历,得到k个最大的频数对应的< ...
最新文章
- R语言dplyr包获取dataframe分组聚合汇总统计值实战(group_by() and summarize() ):均值、中位数、分位数、IQR、MAD、count、unique
- 人工智能和自主系统在美军联合职能中的应用
- 索赔 100 万!只是因为一个开源插件?
- Python3压缩和解压缩实现
- python怎么画圆并改变线条颜色_基于logi的matplotlib中线条颜色的改变
- 数据导出生成word附件使用POI的XWPFTemplate对象
- java声明和初始化数组_Java 中初始化数组
- hdu 1233 最小生成树
- 爬虫实战学习笔记_1 爬虫基础+HTTP原理
- 配置所需要的依赖_配置spring所需要的jar包
- Java案例:压缩与解压缩文件
- windows2008开机占用多少内存_如何提升电脑开机速度?
- 使用Redis进行搜索
- java quartz插件_JFinal Quartz 2.2.1插件
- java long转float_Java中为什么long能自动转换成float类型
- 2020年上半年我国互联网网络安全监测数据分析报告
- 2022年茶艺师(中级)证考试及茶艺师(中级)模拟考试题库
- WebRTC实时通信系列教程7 使用Socket.IO搭建信令服务器交换信息
- python爬取高校课程信息进行选课实战
- 和程序员薪酬差不多的工作