《算法笔记知识点记录》第四章——算法初步2——散列

简介: 《算法笔记知识点记录》第四章——算法初步2——散列

今天继续更新,昨天的排序大家都用明白了么,今天我们来看看hash表,希望大家能和我一起学习呀。每篇文章后面都有对应的练习题哦,我自己会写题解给大家作为参考,好了不bb了,我们开始把!

🧑🏻作者简介:一个从工业设计改行学嵌入式的年轻人

✨联系方式:2201891280(QQ)

📔源码地址:https://gitee.com/xingleigao/algorithm-notes

⏳全文大约阅读时间: 120min(有点长,大家忍一下 ,一定会有蜕变的)

文章目录

☘前言☘

🍘一、相关知识点

🎐1.散列定义与整数散列

🍕2.整数的散列

👻3.字符串hash

🐳课后习题

🍘一、相关知识点

🎐1.散列定义与整数散列

散列(Hash)——将元素通过一个函数转换为整数,使得该整数可以尽量的唯一代表这个元素。


很难理解,但是其实我们会在不知不觉中用到这个知识点,我们先来看一个例子。


给你N个正整数,再给你M个正整数。然后求出这M这个正整数分别在N中出现的次数。

其中M、N中所有元素< 。

输入:7 5 N = [1,2,3,4,5,6,7] M = [1,8,5,4,9]

输出:1 0 1 1 0


最简单的暴力肯定是嵌套循环,每次都去遍历,时间复杂度就达到O(MN)的量级。

我们优化的方式最容易想到的其实是给将N中所有元素映射到数组下标中,然后查表就好了。竞赛中的打表查表也是类似的空间换时间的方式。复杂度就降低到了O(M+N)。


const int maxn = 10010;
int hash[maxn] = {0};        //初始化为全不存在
int ans[maxn];
for(int i = 0;i < nsize;++i)
    hash[N[i]]++;          //建立hash表
for(int i = 0;i < msize;++i)
    ans[i] = hash[M[i]];    //查表输出;
rteurn ans;


上面这种方式虽然简单,但是请务必熟稔于心,尽量使用,使用场景非常多。

🍕2.整数的散列

上面的方式对空间的牺牲过大,当量级达到亿万级根本就不可能使用,所以会有一些常见的散列方式。这里介绍几种常见的方式。


*直接定址法(就是上面的那种)

*除留余数法(将元素对某个值取余,然后将元素放入相应的位置。)

*平方取中法(将元素平方取中间的几位作为转换后的对应位置、不是很常用)


最常用的就是除留余数法H ( k e y ) = k e y H(key) = key % mod;H(key)=key


其中mod由于希望能将所有数字尽量分散到hash表内一般选择素数。

很容易发现由于mod的选择会造成不同元素对应同一个转换后的整数,会产生冲突。

一般来说解决冲突有三种方式


*线性探测法(产生冲突后向后推移几个单位寻找空位插入,很容易产生堆积)

*平方探测法(产生冲突后 按照、、…的方式探测)

8拉链法(将产生冲突的元素用链表链接起来,这算是一个链表的运用了。0.0)

👻3.字符串hash

上面讨论的都是一个整数的hash方法,那么给你一个字符串char s[]怎么去做hash呢? 其实就是去做映射,当我们知道元素个数之后可以将元素映射到一个范围内。

比如:字母a~z可以看作0-26,在c中其实只要 c - 'a'就可以做到了。

但是如果是一个字符串怎么办呢?可以类比于我们平常见到的数字比如123其实就是十进制。

那我们字母表只有26个就可以用26进制来表示这个字符串了

比如abc对应的就是( 123 ) 26 (123)_{26}(123) 26 ,xyz对应的就是( ( 24 ) ( 25 ) ( 26 ) ) 26 ((24)(25)(26))_{26}((24)(25)(26)) 26 。

考虑到我们比较适应于10进制 我们可以做个转换 就是x y z = 24 ∗ 2 6 2 + 26 ∗ 26 + 26 ∗ 1 xyz = 24 *26^2+ 26 *26 + 26 *1xyz=24∗26 ^2 +26∗26+26∗1;

总结:如果是字符串,确定相应字母表中元素个数n,然后转换为n进制数来表示。

以一个例子作为结束

给出N个字符串(每个字符串都是三个大写字母),在给出M个查询字串,问是否在N中出现。

示例输入:2 5 N = [ “ABC” , “CBA] M = [“ABC”, “ABB”,“ABD”,“AAA”,CBA”]

示例输出: 1 0 0 0 1


首先有一个对应转换函数👇


int strtoint(char s[]){        //运用hash函数将字符串转整形
   int ans = 0;
   for(int i = 0;s[i] != '\0;++i){
       ans = ans * 26 + s[i] - 'A';
   }
   return ans;
}


bool hash[Nsize] = {false};
bool ans[Msize] = {false};
for(int i = 0;i < Nsize;++i)    hash[strtoint(N[i])] = true;//插入hash表
for(int i = 0;i < Nsize;++i)    if(hash[strtoint(M[i])])    ans[i] = true;
return ans;
}


🐳课后习题

我写完会放题解,大家写完了可以在评论区打卡哟!题解我放评论区吧,这样不用修改文章。

7d75122a1db30ed2534112671c5bd62.png


题解:评论区见,置顶没有就是我没写完0.0,大佬们刷完打个卡

大家加油冲!!!!


相关文章
|
1月前
|
算法 索引
❤️算法笔记❤️-(每日一刷-141、环形链表)
❤️算法笔记❤️-(每日一刷-141、环形链表)
45 0
|
1月前
|
算法 API 计算机视觉
人脸识别笔记(一):通过yuface调包(参数量54K更快更小更准的算法) 来实现人脸识别
本文介绍了YuNet系列人脸检测算法的优化和使用,包括YuNet-s和YuNet-n,以及通过yuface库和onnx在不同场景下实现人脸检测的方法。
33 1
|
1月前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
57 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
1月前
|
算法
❤️算法笔记❤️-(每日一刷-160、相交链表)
❤️算法笔记❤️-(每日一刷-160、相交链表)
17 1
|
1月前
|
存储 算法
动态规划算法学习一:DP的重要知识点、矩阵连乘算法
这篇文章是关于动态规划算法中矩阵连乘问题的详解,包括问题描述、最优子结构、重叠子问题、递归方法、备忘录方法和动态规划算法设计的步骤。
98 0
|
1月前
|
数据可视化 搜索推荐 Python
Leecode 刷题笔记之可视化六大排序算法:冒泡、快速、归并、插入、选择、桶排序
这篇文章是关于LeetCode刷题笔记,主要介绍了六大排序算法(冒泡、快速、归并、插入、选择、桶排序)的Python实现及其可视化过程。
13 0
|
1月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
30 0
|
1月前
|
算法
❤️算法笔记❤️-(每日一刷-26、删除有序数组的重复项)
❤️算法笔记❤️-(每日一刷-26、删除有序数组的重复项)
23 0
|
24天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
9天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。