数据结构与算法(2)

79 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

现在有一道常见的面试题,比如现在有两个字符串数组,每个数组大约有 10 万条字符串,如何快速找出两个数组中相同的字符串?

内心os:用两个for循环暴力循环吗? No,这是不可以接受的

而如果用Hash表来作为数据结构,就可以完美解决以上问题。

散列函数

散列函数我们可以把它定义成hash(key),其中 key 表示元素的键,hash(key) 的值表示经过散列函数计算得到的散列值。

散列冲突

不同的key对应着同一个散列值的情况我们称为散列冲突。

如何解决散列冲突?

  1. 开放寻址法,如果出现了散列冲突,我们就重新探测一个空闲位置,将其插入。散列表中的数据都存储在数组中,可以有效地利用 CPU 缓存加快查询速度,当数据量比较小、装载因子小的时候,适合采用开放寻址法)
  2. 链表法,相同的散列值用一个链表存取,例如LinkedHashMap(这种方法对装载因子容忍度更高,假设装载因子大于1,也仅仅是链表长度的增加而已,而且也可以把链表更改为红黑树等结构,降低查询效率)

而如果散列冲突次数过多(也就是装载因子过大),链表法拉起了太长的链子,那么查询效率也会大大降低,这时候就可以对散列表进行扩容。

装载因子的计算公式是:

装载因子= 填入表中的元素个数 / 散列表的长度****

  • 假设每次扩容我们都申请一个原来散列表大小两倍的空间。如果原来散列表的装载因子是 0.8,那经过扩容之后,新散列表的装载因子就下降为原来的一半,变成了 0.4。