哈希表理论基础
哈希表(Hash table):哈希表是根据关键码的值而直接进行访问的数据结构.(其实数组就是一张哈希表)哈希表中关键码就是数组的索引下标.
什么时候用哈希法??
当我们遇到要快速判断一个元素是否出现集合里时,就要考虑哈希法.
(至于把所查目标映射到哈希表上就涉及到了hash function “哈希函数”)
过程:一般通过Hashcode把目标(比如:学生名字)转换为数值(一般Hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值),这样就把学生名字映射为哈希表上的索引数字了。
思考:若是数量大于哈希表大小,取模做匀也有可能有几位学生同时映射到哈希表同一个索引下标位置(哈希碰撞就是指小李小王都映射到索引下标同位置)
如图所示:
如何解决哈希碰撞?
①拉链法 ②.线性探测法
① 发生冲突的元素肯定被存储在链表中,这样我们可以通过索引找到小李小王。
(注意:datasize是数据规模。tablesize是哈希表大小.)
拉链法其实就是选择适当的哈希表大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间。
② 要保证tablesize大于datasize。即用哈希表空位来解决碰撞问题.
eg:放了小李,下一个空位放小王,所以要求tablesize>datasize.否则哈希表上就没有空置的位置来存放 冲突的数据了。图示:
常见三种哈希结构: 数组,set(集合),map(映射)
总结:判断一个元素是否出现过的场景也应该第一时间想到哈希法!
242.有效的字母异位词
题目:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
题目链接
分析加代码:
349.两个数组的交集
题目:给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
题目链接
分析加代码
思考与总结:
我们遇到哈希表题目的时候,什么时候用数组,什么时候用set,什么时候用map??
如果数值无限制,可能上亿,哈希映射时,用数组就不合适了,因为数组下标放不了那么大的数,也浪费了存储空间。
那么此时会想为什么会用到哈希表这种方式来解决??
哈希表最擅长解决,给你一个元素判断在这个集合里是否出现过。你这里面的数值,可能也不是很大,但数值分布很分散(eg:0,30,1000)所以用set比较合适。而map自身(key,value)就可以判断何时选它。
202.快乐数
题目:编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
eg: 输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
分析加代码
本题思路关键在于:每次相加结果是多次出现的,所以以此为突破关键,如果是正常快乐数,则sum会最后为1,如果sum结果重复出现,说明是死循环,肯定不能为1,所以也就不是快乐数。
1.两数之和
题目:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案
题目链接
分析加代码
思路:例子:{2,7,3,6}。target=9。当指向第一个元素时,需7为9,所以去map里查询7是否含有,但遍历是第一个元素,map还没有存放遍历过的元素,所以map为空,接下来指向下一个元素时,map才会存遍历过的元素,2已经遍历过,所以2就放到map里面了,下一个元素是7需要2,所以去map里面看是否含有2,发现里面有存放2,最后找到两个对应的下标,返回一个数组里面去,所以满足题意。
注意与补充: 代码行map.containskey(key)表示得到map中key对应的value.而不是key.
今天任务量好大,算法虽然魅力大,但好花费时间呀!!!!!一定三刷以上!!!!!加油
【补充一下,所有有关插图知识类照片(除过代码图示)均保存自卡哥代码随想录,支持卡哥!冲】