【学习笔记】数据结构(哈希表基础+哈希集合+哈希映射+计数+查找)

一、 哈希函数

哈希函数:Hash(key)=key%TableSize

作用:把关键字 key 映射到哈希数组的下标

TableSize:哈希表长度,一般选质数,减少冲突

缺陷:不同 key 取模后得到相同下标 -> 哈希冲突

  1. 哈希冲突解决方式

1、开放寻址法

如果该下标已有元素,向后找空位存放;缺点:删除麻烦、容易聚集,简单题偶尔用。

2、拉链法(链地址法,最常用!)

哈希表每个位置是一条链表;发生冲突的元素直接挂在对应下标的链表上。

优点:增删简单、不容易堆积;手写哈希首选。

  1. 哈希集合 HashSet(逻辑概念)

功能:只保存元素,不保存对应数值,元素不可重。

适用场景:1、判断某个数是否存在

2、数组去重

C 语言实现方式:布尔数组 bool hash ,存在置 1,不存在置 0。

  1. 哈希映射 HashMap(键值对 key->value)

功能:保存key(关键字)和value(对应数据)

适用场景:统计元素出现次数、建立数值与下标、数值与次数的映射

C 语言实现:int 数组 hash\[\],hash key = 次数 / 对应值

重要限制:数组模拟哈希只适合 key 范围不大、非负数;

如果 key 存在负数、数值极大(如 1e9),只能手写拉链法链表哈希。

二、时间复杂度总结

理想无冲突:插入、查找、删除

冲突很多(链表很长):退化到

三、数组模拟哈希表使用规则

1、先预估数据范围,开辟足够大数组

2、负数处理:统一加上偏移量变成正数 key + offset

3、集合模拟:bool hN

存入:hkey=true

判断存在:if(hkey)

4、映射 / 计数模拟:int hN

计数:hkey++

获取次数:hkey

四、高频考点区分

1、哈希集合(bool 数组):只关心有没有

判断存在、去重

2、哈希映射(int 数组):关心对应的值 / 次数

统计频次、一一映射

五、易错重点

1、数组下标不能为负数!遇到负数 key 必须加偏移。

2、哈希表数组不要开太小,否则越界;全局数组放在静态区,空间更大。

3、多次测试用例,一定要清空哈希数组!memset 重置

4、取模运算表长尽量质数,减少冲突。

5、数组模拟哈希有数值范围限制;超大数必须链表实现。

题目一:理解:给一个整数数组 nums

如果数组有数字出现 >= 2 次 -> 返回 true

如果数组全部数字互不重复 -> 返回 false

关键点:只要求全局出现两次就行,不需要位置相邻。

思路:排序+相邻比较

1、将数组从小到大排序

2、排序完成后,相等的数字一定紧紧相邻

3、遍历数组,判断当前元素和下一个元素是否相等,相等返回 true

出现了错误:C 语言不允许在函数体内写#include,也不能在一个函数里面定义另一个函数(cmp

写在 containsDuplicate 里面属于嵌套函数,LeetC 编译器不支持),直接引发编译报错。

正确的:

1、qsort所需要的比较回调函数

2、强制转换成int指针,取出数值,实现从小到大排序

步骤一:调用qsort对数组升序排序

原始数组重复数字是分散的,无法简单判断。排序之后,相同的值一定会紧紧挨在一起。

步骤二:书写for循环,循环条件i < numsSize -1

依次取出数组每一个元素,准备和它后一位元素比较。

循环内部要访问numsi+1。假设数组一共 4 个元素,下标 0,1,2,3。

步骤3:if判断numsi == numi+1

检测当前位置和下一个位置数字是否相等。

经过排序,相等数字一定相邻。只要任意一种相邻数字相等,就证明数组存在重复元素。

步骤四:循环全部走完,执行return false

最终返回结果。

只有当整个循环完整跑完,全程没有找到任何一对相等的相邻元素,才能确定数组中不存在重复数字,此时返回false。

第二题:

思路:小写字母一共只有 26 个,我们开辟大小 26 的数组充当哈希表。

第一轮遍历字符串:统计每一个字符出现次数;

第二轮再次从头遍历字符串:按照原始顺序查找第一个出现次数等于 1的字符,直接返回它的下标;

两轮遍历结束没有找到,返回 - 1。

重点:必须两轮遍历。不能遍历哈希数组去找答案,会丢失字符串原本先后顺序!

步骤一:创建技术数组int cnt26 = 0;

充当哈希映射,存放26个小写字母出现次数,初始全部置0。

26个是因为题目字符串只有小写英文字母a~z,刚好26个。

映射规则:si - 'a' 把字符转为 0~25 的数组下标。

步骤二:第一轮for循环,统计字符出现次数

扫描一遍字符串,把每个字母出现多少次统计到哈希函数。

我们需要知道每个字符总共出现几次,才能判断是不是唯一字符。

步骤3:第二轮for循环,从头查找第一个次数 =1 的字符

按照字符串原始顺序遍历,找到第一个只出现一次的字符,返回下标。

cnt 数组是按 a-z 顺序存放,丢失字符串先后顺序。

步骤四:循环走完,执行return-1

所有字符出现次数都>=2,不存在唯一字符,按题目要求返回 - 1。

只有第二轮完整遍历结束,全程没有找到次数等于 1 的字符,才执行这条语句。

相关推荐
kaixin_啊啊1 小时前
中国研究生数学建模竞赛(华为杯)学习笔记——数据预处理全流程
人工智能·笔记·学习·数学建模·ai·大模型·数据预处理
shirsl3 小时前
算法 Day1-数组 / 哈希 + 双指针
python·算法·哈希算法
dadaobusi7 小时前
学习:RV lkvm SBI
java·学习·spring
传奇开心果编程9 小时前
【Xilem 0.4 基础语法学与练】第一课:从零到计数器
学习·rust·前端框架
David猪大卫10 小时前
【C++修炼】智能指针使用及原理
开发语言·c++·经验分享·笔记·学习·考研·面试
z23456d10 小时前
第四十一天学习心得
学习
sunflower#11 小时前
Go学习第五阶段:接口、泛型与包设计,实现可替换的通讯录存储层
学习·oracle·golang
不会就选b11 小时前
算法日常・每日刷题--<贪心>7
数据结构·算法·leetcode
dadaobusi11 小时前
RV设备透传:主线尚未支持
学习