【数据结构】Hash表简介及leetcode两数之和python实现
Hash表简介
基本思想
哈希存储的基本思想是根据当前待存储数据的特征,以记录关键字(key)为自变量,设计一个哈希函数Hash,根据Hash计算出对应的函数值Hash(key),以这个值(哈希地址)作为数据元素的地址,并将数据元素存入到相应地址的存储单元中。按照这个思想构造的表就叫做哈希表(Hash table,也叫散列表)
查找时再根据要查找的关键字key采用同样的函数计算出哈希地址,然后根据Hash(key)直接到相应的存储单元中去取要找的数据元素即可。
建立步骤
step 1:取数据元素的关键字key,计算其哈希函数值(地址)。若该地址对应的存储空间还没有被占用,则将该元素存入;否则执行step2解决冲突。
step 2:根据选择的冲突处理方法,计算关键字key的下一个存储地址。若下一个存储地址仍被占用,则继续执行step 2,直到找到能用的存储地址为止。
问题
对于n个数据元素的集合,总能找到关键字与存放地址一一对应的函数。假设最大关键字为m,可以分配m个数据元素存放单元,选取函数Hash(key)=key即可,但是这样会造成存储空间的很大浪费,甚至不可能分配这么大的存储空间。通常关键字的集合比哈希地址集合大得多(tips:这里的大不是说个数,而是总体所用空间),因而经过哈希函数变换后,可能将不同的关键字映射到同一个哈希地址上,这种现象称为冲突(Collision)。映射到同一哈希地址上的关键字称为同义词。可以说,冲突不可能避免,只能尽可能减少。
Hash表实现
通过文章前面的了解我们可以知道,具体去实现Hash表需要我们完成:1)Hash函数构造;2)制定解决冲突的方案。
Hash函数构造
构造哈希函数的方法有很多,总的原则是尽可能简单,以便提高转换速度,且要尽可能将关键字集合空间均匀的映射到地址集合空间中,同时尽可能降低冲突发生的概率。
下面是一些常用的哈希函数构造方法:
直接地址法
Hash(key) = a*key + b(a、b为常数)
除数留余法
H(key) = key % p (p ≤ m)
取关键字除以p的余数作为哈希地址,p最好选择一个小于或等于m(哈希地址集合的个数)的某个最大素数,也可以是不包含小于20质因子的合数。
哈希表长度 8 16 32 64 128 256 512
最大素数 7 13 31 61 127 251 503
数字分析法
设关键字集合中,每个关键字均由m位组成,每位上可能有r中不同的符号。数字分析法根据r种不同符号及在各位上的分布情况,选取某几位,组合成哈希地址。所选的位应是各种符号在该位上出现的概率大致相同。平方取中法
对关键字平方后,按哈希表大小,取中间的若干位作为哈希地址。折叠法(Folding)
比如key=135790,要求Hash(key)是2位数的散列值。那么我们将key变为13+57+90=160,然后去掉高位“1”,此时Hash(key)=60,这就是他们的哈希关系,这样做的目的就是地址与每一位的key都相关,来做到“散列地址”尽可能分散的目地。
冲突处理方法
影响哈希查找效率的一个重要因素是哈希函数本身。当两个不同的数据元素的哈希值相同时,就会发生冲突。为减少发生冲突的可能性,哈希函数应该将数据尽可能分散地映射到哈希表的每一个表项中。
解决冲突的方法有以下两种:
开放地址法
所谓开放定址法,即由关键字得到的哈希地址一旦产生了冲突,也就是说,该地址已经存放了数据元素。我们需要寻找下一个空的哈希地址,只要哈希表足够大,空的哈希地址总能找到,并将数据元素存入。常用的找空哈希地址方法有下列三种。
(1)线性探测法Hi=(Hash(key)+di)%m(1=<i<m)
其中,Hash(key)为哈希函数,m为哈希表长度,di为增量序列1,2…,m-1,i为探测次数。
(2)二次探测法地址增量序列为:di=12,−12,22,−22,...,q2,−q2(q≤m/2)d_i = 1^2, -1^2,2^2,-2^2 ,...,q^2,-q^2 (q ≤ m/2)di=12,−12,22,−22,...,q2,−q2(q≤m/2)
(3)双哈希函数探测法Hi =( H(key) + i * RH(key) )%m ( i = 1,2,3,..., m-1 )
H(Key) , RH(Key) 是两个哈希函数,m为哈希表长度。
先用第一个哈希函数对关键字计算哈希地址,一旦产生地址冲突,再用第二个函数确定移动的步长因子,最后通过步长因子序列由探测函数寻找空余的哈希地址。H1 = ( a+b )%m , H2 = ( a + 2b )%m , ... , Hm-1 = ( a+(m-1)*b )%m
链地址法
将哈希值相同的数据元素存放在一个链表中,在查找哈希表的过程中,当查找到这个链表时,必须采用线性查找方法。
leetcode两数之和python实现
题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]
基于Hash思想的实现
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
Hash_dict = {}
for i in range(len(nums)):
Hash_dict[nums[i]] = i
for i in range(len(nums)):
temp = target - nums[i]
if temp in Hash_dict & i != Hash_dict[temp]:
return [i,Hash_dict[temp]]
【数据结构】Hash表简介及leetcode两数之和python实现的更多相关文章
- leetcode 两数之和 python
两数之和 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 1 ...
- LeetCode两数之和-Python<一>
下一篇:LeetCode链表相加-Python<二> 题目:https://leetcode-cn.com/problems/two-sum/description/ 给定一个整数数组和一 ...
- LeetCode两数之和
LeetCode 两数之和 题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是 ...
- leetcode - 两数之和Ⅳ 输入BST(653)
题目描述:给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true. 解题思路:根据二叉搜索树的特点,对二叉搜索树进行中序遍历可以得到一个从小到达排 ...
- Leetcode -- 两数之和Ⅰ
1. 两数之和 题目描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标. 示例:给定 nums = [2, 7, 11, 15 ...
- leetcode两数之和go语言
两数之和(Go语言) 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复 ...
- Leetcode 两数之和 (散列表)
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...
- leetcode 两数之和 II - 输入有序数组
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的下标值 ...
- leetcode NO.1 两数之和 (python实现)
来源 https://leetcode-cn.com/problems/two-sum/description/ 题目描述 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个 ...
随机推荐
- base64和blob
base64是二进制数据的一个编码格式,就像utf8一样的东西,他跟json一样,也是前后端交互能够相互识别的数据,他更多的是用来传递文件数据,并且如果是图片的base64,可以用来压缩 获取base ...
- use matplotlib to drew a table
$sudo apt-get install python3-matplotlib gyf@gyf-VirtualBox:~$ python3Python 3.6.9 (default, Nov 7 ...
- 浅析Java NIO
浅析Java NIO 前言 在说NIO之前,先来说说IO的读写原理.我们都知道Java中的IO流可以分为网络IO流和文件IO流,前者在网络中使用,后者在操作文件时使用.但实际上两种流区别并不是太大 ...
- ffmpeg 多路实时问题之解决思路
记得前面有人提出多路视频不实时问题,这个首先需要从网络带宽上查看是否视频帧全实时的到达,还有一个问题就是,即使视频帧全部到达,看起CPU也是足够的,但是却表现为慢镜头这种样子,那么很可能是解码显示的 ...
- 概率图模型之EM算法
一.EM算法概述 EM算法(Expectation Maximization Algorithm,期望极大算法)是一种迭代算法,用于求解含有隐变量的概率模型参数的极大似然估计(MLE)或极大后验概率估 ...
- 开源DDD设计模式框架YMNNetCoreFrameWork第四篇-增加YMNSession,增加异常处理,增加策略授权
1.增加YMNSession,可以获取当前登录的用户信息 2.增加异常处理,不要使用过滤器,过滤器只能获取到mvc异常 3.增加策略授权,策略授权支持用户角色.用户名授权,初步实现 代码地址:http ...
- 七十八、SAP中数据库操作之查询条数限制
一.UP TO <数量> ROWS,表示查询出多少条数据 二.效果如下
- 七十、SAP中内表批量指定位置插入
一.代码如下 二.调试一下 三.被插入的数据 四.效果如下
- redis在.Net程序中使用
1.设置访问密码 config 2.连接redis服务器 private static string redisHost = ConfigHelper.GetAppSetting("redi ...
- FindWindowXG
测试: 函数代码: function FindWindowXG(strClass, strTitle: string): THandle; var hd: THandle; arrClass: ..] ...