散列(hash)是常用的算法思想之一,在很多程序中都会有意无意地使用到。

  先来看一个简单的问题:给出N个正整数,再给出M个正整数,问这M个数中每个数分别是否在N个数中出现过。

例如N=5,M=3,N个正整数{8,3,7,6,2},欲查询的M个正整数为{7,4,2},于是后者只有7和2在N个正整数中出现过,

而4是没有出现过的。

  对于这个问题,最直观的思路是:对每个欲查询的正整数x,遍历所有的N个数,看是否有一个数与x相等。这种

做法的时间复杂度为O(MN),当N和M都很大时,时间复杂度显然太大!

  那么该如何做呢?--不妨用空间换时间,即设定一个bool型数组hashTable[100001],其中hashTable[x]=true;表示

整数x在N中出现过,而hashTable[x]=false表示正整数x没有在N中出现过。这样就可以在一开始读入N个正整数时就进

行预处理,即当读入x时,就令hashTable[x]=true;(说明:hashTable数组需要初始化为false,表示初始状态下所有数

都没有出现过)。于是,对M个欲查询的数,就能够直接通过hashTable数组判断每个数是否出现过。显然这种做法的

时间复杂度为(N+M),代码如下:


  同样的,如果题目要求M个欲查询的数中每个数在N个数中出现的次数,那么可以把hashTable数组替换为int型,然后

在输入N个数时进行预处理,即当输入的数为x时,就令hashTable[x]++;这样就可以用O(N+M)的时间复杂度输出每个欲查询

的数出现的次数。代码如下:

  上面的问题都有一个特点,那就是直接把输入的数作为数组的下标来对这个数的性质进行统计。这是一个很好的用空间

换时间的策略,因为它将查询的复杂度降到了O(1)级别。但是,这个策略暂时还有一个问题--上面题目中的每个数都不会超过

105,因此直接作为数组下标是可行的,但是如果输入可能是109大小的整数,或者甚至是一个字符串(例如"I love you“),就不能

将它们直接作为数组下标了。要是有一种做法,可以把这些乱七八糟的元素转化为一个在能接受范围内的整数,那该多么美好呀!

  这样的做法当然是存在的,那就是散列(hash)。一般来说,散列可以浓缩成一句话”将元素通过一个函数转化为整数,使得

该整数可以尽量唯一地代表这个元素“。其中把这个转化函数称为散列函数H,也就是说,如果元素在转化前为key,那么转化后就

是一个整数H(key)。

  那么key是整数的情况来说,有哪些常用的散列函数呢?一般来说,常用的有直接定址法,平方取中法,除留余数法等

未完待续……

散列(hash)的更多相关文章

  1. StackExchange.Redis帮助类解决方案RedisRepository封装(散列Hash类型数据操作)

    本文版权归博客园和作者本人共同所有,转载和爬虫请注明本系列分享地址:http://www.cnblogs.com/tdws/p/5815735.html 上一篇文章的不合理之处,已经有所修改. 今天分 ...

  2. 散列(Hash)表入门

    一.概述 以 Key-Value 的形式进行数据存取的映射(map)结构 简单理解:用最基本的向量(数组)作为底层物理存储结构,通过适当的散列函数在词条的关键码与向量单元的秩(下标)之间建立映射关系 ...

  3. Redis散列(Hash)的相关命令

    散列 就像一个减配的Redis 内部及其类似Java的Map 内容就是key:value结构 hash类型在面向对象编程的运用中及其适合,因为它可以直接保存编程语言中的实体类关系 增 hset hse ...

  4. 非对称算法,散列(Hash)以及证书的那些事

    转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/35389657 作者:小马 这几个概念在金融电子支付领域用得比較多,我忽然认为把它们 ...

  5. john快速破解各种散列hash

    0x01 john工具安装: kali系统自带的有,也可以自己安装在其他linux和windows系统上,关于安装步骤网上都有可自行百度. 0x02 john常用选项 具体的其他选项可通过john - ...

  6. [No0000132]正确使用密码加盐散列[译]

    如果你是一个 web 开发工程师,可能你已经建立了一个用户账户系统.一个用户账户系统最重要的部分是如何保护密码.用户账户数据库经常被黑,如果你的网站曾经被攻击过,你绝对必须做点什么来保护你的用户的密码 ...

  7. Redis从基础命令到实战之散列类型(Hash)

    从上一篇的实例中可以看出,用字符串类型存储对象有一些不足,在存储/读取时需要进行序列化/反序列化,即时只想修改一项内容,如价格,也必须修改整个键值.不仅增大开发的复杂度,也增加了不必要的性能开销. 一 ...

  8. 线性探测再散列 建立HASH表

    根据数据元素的关键字和哈希函数建立哈希表并初始化哈希表,用开放定址法处理冲突,按屏幕输出的功能表选择所需的功能实现用哈希表对数据元素的插入,显示,查找,删除. 初始化哈希表时把elem[MAXSIZE ...

  9. PAT A1145 Hashing - Average Search Time (25 分)——hash 散列的平方探查法

    The task of this problem is simple: insert a sequence of distinct positive integers into a hash tabl ...

随机推荐

  1. struts2 下载

    struts  官网 : https://struts.apache.org/

  2. 依赖注入【转自知乎 PHP】

    第一章:小明和他的手机 从前有个人叫小明 小明有三大爱好,抽烟,喝酒…… 咳咳,不好意思,走错片场了.应该是逛知乎.玩王者农药和抢微信红包 <img src="https://pic1 ...

  3. expandableListview的默认箭头箭头怎样移到右边

    1 . ExpandableListView布局:<ExpandableListView    android:id="@+id/bbs_category_expandable_lis ...

  4. bzoj 1497(最大权闭合子图)

    1497: [NOI2006]最大获利 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 6410  Solved: 3099[Submit][Status] ...

  5. Flask开启多线程、多进程

    一.参数 app.run()中可以接受两个参数,分别是threaded和processes,用于开启线程支持和进程支持. 二.参数说明 1.threaded : 多线程支持,默认为False,即不开启 ...

  6. 2010–2011, NEERC, Northern Subregional C.Commuting Functions

    C.Commuting Functions 由于要求答案字典序最小,我们肯定希望从g(1)开始对函数g进行赋值,于是又公式f(g(x))=g(f(x)) 设f(x)=i 我们推导出 由于f是双射,当i ...

  7. 慕课网2-5 编程练习:通过jQuery通配符选择器进行文字变色

    2-5 编程练习 请请使用*选择器将div标签中的字体颜色变成红色 效果图: 任务 (1)使用通配符选择器 (2)使用jQuery的.css()方法设置样式,语法css('属性 '属性值') 参考代码 ...

  8. Photoshop CC2019破解版

    Photoshop CC2019 精简版: 链接:https://pan.baidu.com/s/1PeFrhtLHxLRXCW_vMkAZDg  提取码:q6nl Photoshop CC2019: ...

  9. PHP的包依赖管理工具Composer简介

    composer是一个基于项目的依赖管理器,负责将php项目的所依赖的包和库安装在项目的目录中,默认不会不会安装任何数据到全局.他用于取代之前pear工具 1 安装Composer curl -sS  ...

  10. ACM_求f(n)

    求f(n) Time Limit: 2000/1000ms (Java/Others) Problem Description: 设函数f(n)=1*1*1+2*2*2+3*3*3+...+n*n*n ...