哈希表(Hash Table)

二分搜索中提到了在有序集合中查询某个特定元素的时候,通过折半的方式进行搜索是一种很高效的算法。那能否根据特征直接定位元素,而非折半去查找?哈希表(Hash Table),也称为散列表,就是一种数据结构,用于实现键-值对的映射关系。它通过将键映射到特定的值(哈希值)来实现快速的数据检索。

	// Java 中Hash表JDK中有提供两种结构Hashtable、HashMap,使用接口上区别不大
// Hashtable 是Dictionary类的子类,而 HashMap 是AbstractMap类的子类。
// 由于 Dictionary类已经被废弃,因此Hashtable也不再推荐使用。
// 在工程应用上值得注意的是 Hashtable是线程安全的,而HashMap不是 public HashMap<Integer,Long> records1 = new HashMap<>();
public Hashtable<Integer,Long> records2 = new Hashtable<>();

一般而言,哈希表基于哈希函数将键转换为哈希码,然后使用这个哈希码作为索引获取相应的元素。哈希表的优点是具有快速的平均查找时间,通常为O(1)。然而,它也具有一些挑战,如处理哈希冲突、设计良好的哈希函数和维护适当的装载因子。装载因子表示哈希表已用空间与总空间的比例,需要适时进行动态调整以保持哈希表的性能。

	// 示例java中初始化 HashMap的容量以及装载因子。
Map<Integer,Integer> sumMap = new HashMap<>(2000,0.75f);

哈希表在计算机科学中有广泛的应用,包括实现关联数组、数据库索引、缓存、编程语言中的字典和集合等等。

基本概念

哈希函数(Hash Function): 哈希表使用哈希函数来将键转换为整数,通常是数组的索引。哈希函数应该是确定性的,即对于相同的键,它应该生成相同的哈希码。理想情况下,不同的键应该映射到不同的哈希码,但由于哈希函数的有限性,可能会出现哈希冲突。

哈希冲突(Hash Collision): 当两个不同的键映射到相同的哈希码时,发生哈希冲突。哈希表需要处理哈希冲突,以确保不同的键可以正确存储和检索。

存储结构: 哈希表通常由一个数组和一个哈希函数组成。数组的每个元素称为桶(Bucket),它可以存储一个或多个键-值对。

PS:Java 中由于都已经封装好了 HashMap,一般使用可能感知不到这些概念,但要熟练掌握还是需要理解这些基本理念。

基本操作

插入(Insertion): 将键-值对插入哈希表时,首先通过哈希函数计算键的哈希码,然后确定存储位置(桶)。如果存在哈希冲突,通常会使用链表、数组或其他数据结构来解决冲突,并将键-值对添加到存储位置。

查找(Lookup): 查找键对应的值时,使用相同的哈希函数计算哈希码,并在存储位置中查找该键。如果存在哈希冲突,必须在冲突的元素中搜索以找到正确的键-值对。

删除(Deletion): 删除键-值对时,使用相同的哈希函数计算哈希码,然后从存储位置中删除对应的键-值对。

基本应用

Leetcode 383 赎金信【简单】

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

字符可以转换成ASCII数字,数组的下标也是数字。那么利用这种数字映射作为哈希函数,就能够通过字符直接读取数组存储的信息。通过ASCII数组 来记录 magazine 里面包含的各个字符数量,再遍历 ransomNote 使用到的字符判断是否存在于 ASCII数组,并减少数量来标识已经使用过。

借这题不妨讲一讲分块的编码风格。在日常生活中,我们一定有记忆手机号码的经历,一个长长的数字串(比如1234567890)可能很难记忆,但如果将其分成更小的组块,例如(123) 456-7890,就更容易记忆和处理。这个其实在认识心理学里面概念叫:"信息分块"(chunking),_指的是将大量的信息分割成更小的、有意义的单元,以便更容易处理和记忆。_关键点是人类大脑通过将信息分成较小的组块,可以更有效地处理和记忆信息。

所谓代码可读性其实就是对代码的认识,将信息认识心理学的分块理论应用到代码可读性就是提倡的 分块编码。可以将冗余的代码分成一块一块的逻辑,块与块之间用空行来进行视觉上的分块,方便小段小段的去理解代码逻辑;每一块代码可以适当的加上注释以方便阅读。当然这些都是形式上的,更重要的是每一块代码逻辑都会聚焦一个目标,这样写法也有利于编码者自身对逻辑的梳理以及减少bug。

不妨练习下类似问题,参考代码就不附上了,相信一定能够完成。

Leetcode 242. 有效的字母异位词【简单】

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

更多应用

Leetcode 560. 和为 K 的子数组【中等】

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。

子数组是数组中元素的连续非空序列。

Leetcode 3 无重复字符的最长子串【中等】

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

数据结构与算法 | 哈希表(Hash Table)的更多相关文章

  1. 算法与数据结构基础 - 哈希表(Hash Table)

    Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...

  2. 数据结构 哈希表(Hash Table)_哈希概述

    哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...

  3. PHP关联数组和哈希表(hash table) 未指定

    PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...

  4. python数据结构与算法——哈希表

    哈希表 学习笔记 参考翻译自:<复杂性思考> 及对应的online版本:http://greenteapress.com/complexity/html/thinkcomplexity00 ...

  5. Java数据结构和算法 - 哈希表

    Q: 如何快速地存取员工的信息? A: 假设现在要写一个程序,存取一个公司的员工记录,这个小公司大约有1000个员工,每个员工记录需要1024个字节的存储空间,因此整个数据库的大小约为1MB.一般的计 ...

  6. 什么叫哈希表(Hash Table)

    散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构 ...

  7. 词典(二) 哈希表(Hash table)

    散列表(hashtable)是一种高效的词典结构,可以在期望的常数时间内实现对词典的所有接口的操作.散列完全摒弃了关键码有序的条件,所以可以突破CBA式算法的复杂度界限. 散列表 逻辑上,有一系列可以 ...

  8. golang数据结构之散哈希表(Hash)

    hash.go package hash import ( "fmt" ) type Emp struct { ID int Name string Next *Emp } //第 ...

  9. 哈希表(Hash table)

  10. Redis原理再学习04:数据结构-哈希表hash表(dict字典)

    哈希函数简介 哈希函数(hash function),又叫散列函数,哈希算法.散列函数把数据"压缩"成摘要,有的也叫"指纹",它使数据量变小且数据格式大小也固定 ...

随机推荐

  1. hexo博客Yilia主题首页菜单中文乱码解决方案

    方案一: 菜单设置成中文显示,编辑博客根目录下的_config.yml文件 设置language字段如下: language: zh-Hans 或者 language: zh-CN 取决于你的主题th ...

  2. Flutter ncnn 使用

    Flutter 实现手机端 App,如果想利用 AI 模型添加新颖的功能,那么 ncnn 就是一种可考虑的手机端推理模型的框架. 本文即是 Flutter 上使用 ncnn 做模型推理的实践分享.有如 ...

  3. MybatisPlus的各种查询方法

    MybatisPlus的各种查询方法 合并转载于https://my.oschina.net/u/241218/blog/1838534/和https://my.oschina.net/u/24275 ...

  4. ubuntu安装msf签名认证失败

    添加命令 apt-get --allow-unauthenticated upgrade 来允许未认证签名软件安装,但是可能有恶意软件安装进来,可以使用 sudo apt-key adv --keys ...

  5. 使用gulp.js打包layuiAdmin

    安装nvm 在nvm目录下,找到settings.txt,追加以下两行加速nvm(淘宝镜像)node_mirror: https://npm.taobao.org/mirrors/node/npm_m ...

  6. 【教程】青少年CTF机器人使用教程

    前言 本期教程适用于版本号为2.0.1-Beta的青少年CTF机器人,其他版本可能与当前版本不同. 由于之前版本的机器人重构,所以我们细化了本次的机器人逻辑,并且对机器人的功能进行了一些升级. 机器人 ...

  7. CSS3新增了哪些选择器?(属性、结构伪类、伪元素选择器)

    在css3提供的新选择器之前,选择一个元素需要借助id或者class,css3新增的选择器可以更灵活的去选择需要的元素,那css3提供了哪些好用的选择器呢? 首先就是属性选择器,我们可以通过属性选择器 ...

  8. oracle数据备份和还原

    前言 用户:userzs 密码:passzs IP和端口:192.168.0.10:1521/orcl oracle版本:11和12 oracle自带exp和expdp程序用于数据导出备份,imp和i ...

  9. 《小白WEB安全入门》01. 扫盲篇

    @ 目录 基础知识 什么是WEB 什么是前端 什么是后端 什么是数据库 什么是协议 什么是WEB安全 什么是服务器 什么是IP地址.端口 什么是局域网.广域网.内网.外网 什么是URL 什么是MAC地 ...

  10. Antd Form表单中Input输入框 在IE9下按下任何按键都会报校验失败

    antd Form表单中Input输入框 在IE9下按下任何按键都会报校验失败,导致输入框输入不了任何内容! 可能你的react及react-dom版本由于过高导致antd组件不能兼容,需要对reac ...