哈希表总结

理论基础

  • 存储实现:
    (哈希表的底层是数组)
    实现哈希表的两种方法:
    1、数组+链表
    2、数组+红黑二叉树
  • 主要用途:快速判断一个元素是否出现在集合中
  • 查找时间复杂度:一般是O(1),极端情况下哈希碰撞造成的O(n)
    hash表一般都会将要查找的值存在哈希表内,查询的时候直接通过引索查询即可
    将值映射到哈希表上的这个过程就 使用到了 哈希函数

哈希函数

  • 一般通过 hashCode 将 值 转化为引索存入 ,即将 值(传入的key) 映射到hash table 上
  • 如果 值 的总数比 hash table 的size 要大,那么再怎么经过 hashCode 处理,不同的值也会使用相同的索引,此时就产生了 哈希碰撞

哈希碰撞

  • 一般解决哈希碰撞有两种方法

拉链法

  • 在每个hash table 的每个索引处, 存放一个链表的地址,当发生 哈希碰撞 时,就将冲突的元素全部放入链表中,这样就可以通过 引索 + 遍历链表 找到目标元素了
  • 拉链法主要是需要选择适当的哈希表大小,这样既不会因为数组空值太多而浪费空间,也不会因为链表太长而在查找上消耗太多时间。

线性探测法

  • 前提是 tableSize > dataSize,也就是将产生哈希碰撞的值存入 哈希表的空位中

实现哈希表的数据结构

一般通过三种方式:

  • 数组
  • set(集合)
  • map(映射)

Java中:

  • HashSet 基本使用 HashMap 来实现,key 存值,value 存一个虚拟的Object对象定义为static final
  • HashMap 实现:数组 + 链表

三种结构的使用情景

  • 数组:使用数组作为hash表,好处是空间小,简单有效。
    例如:383. 赎金信中要求只有小写字母,那么使用数组就很合适
  • set:使用set比数组好的点
    • 数组的大小是有限的,受到系统栈空间的限制
    • 如果数组空间足够大,但哈希值比较少,比较分散,那么数组造成非常多的空间浪费
      例如题目:202. 快乐数
  • map:使用map的情况是为了存储两个先关联的值,这一点set做不到
    例如:1. 两数之和中可以用key存储值,value存储值对应的下标
    454. 四数相加 II中用key存 A+B 值,value 存 A+B 的出现次数

总结

  1. 当我们需要快速判断一个元素是否出现在集合中时,就要考虑哈希法
    是一种 牺牲空间 换取 时间 的方法
  2. 当需要存储 比较多的元素 同时 还需要 小于线性时间查找对应元素,考虑HashSet
  3. 当需要对应存储 值 与 值出现的次数 或者 值 与 值的引索 时考虑使用HashMap

参考

Carl:https://mp.weixin.qq.com/s/1s91yXtarL-PkX07BfnwLg
samniwu:https://blog.csdn.net/samniwu/article/details/90550196
隐者自怡悦:https://blog.csdn.net/YYQ_QYY/article/details/105992427

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值