哈希表

leetcode(1) 寻找数组中多数(两个、三个、或者任意)之和为一个给定值

為{幸葍}努か 提交于 2020-01-21 22:26:41
目录 一、 题目<两数之和> easy 1. 解题思路 1)暴力解题法 2)两遍哈希表 3)一遍哈希表 二、题目《三数之和》medium 1. 解题思路(排序+双指针) 三、题目《四数之和》medium 1.解题思路(排序+双指针) 一、 题目<两数之和> easy 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。 假设每种输入只会对应一个答案。但是,不能重复利用这个数组中同样的元素。 1. 解题思路 遍历数组元素,对于每一个元素A,寻找数组中是否含有另一个元素B使得A+B=目标值,第一个元素A肯定是需要遍历整个数组的,寻找第二个元素B的方式将决定算法的效率,如果需要一种更有效的方法来检查数组中是否存在目标元素。保持数组中的每个元素与其索引相互对应的最好方法是什么?哈希表。 1)暴力解题法 class Solution { public int[] twoSum(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { if (nums[j] == target - nums[i]) { return new int[] { i, j }; } } }

LeetCode记录 1

谁说我不能喝 提交于 2020-01-20 01:23:34
leetcode 两数之和 tag == 数组 难度 == 简单 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 两种思路: 1.暴力遍历 2.利用哈希表 创建一个哈希表 为了对运行时间复杂度进行优化,我们需要一种更有效的方法来检查数组中是否存在目标元素。如果存在,我们需要找出它的索引。保持数组中的每个元素与其索引相互对应的最好方法是什么?哈希表。 通过以空间换取速度的方式,我们可以将查找时间从 O(n)O(n) 降低到 O(1)O(1)。哈希表正是为此目的而构建的,它支持以 近似 恒定的时间进行快速查找。我用“近似”来描述,是因为一旦出现冲突,查找用时可能会退化到 O(n)O(n)。但只要你仔细地挑选哈希函数,在哈希表中进行查找的用时应当被摊销为 O(1)O(1)。 一个简单的实现使用了两次迭代。在第一次迭代中,我们将每个元素的值和它的索引添加到表中。然后,在第二次迭代中,我们将检查每个元素所对应的目标元素(target - nums[i])是否存在于表中

C#写算法之散列表

谁说胖子不能爱 提交于 2020-01-19 12:08:19
散列表也叫哈希表(hash table),这种数据结构提供了键(Key)和值(Value)的映射关系。 只要给出一个Key,就可以高效地查找到它所匹配的Value,时间复杂度接近于O(1)。 哈希表之所以查询效率这么高,是因为有一个中转站: 本质上,哈希表也是一个数组,但数组是通过下标访问值,所以,输入的key可以从一个中转站中,通过某种方式,把Key和数组下标进行转换。这个中转站就叫作哈希函数。 在不同的语言中,哈希函数的实现方式不一样。 在Java及大多数面向对象的语言中,每一个对象都有属于自己的hashcode,这个hashcode是区分不同对象的重要标识。无论对象自身的类型是什么,它们的hashcode都是一个整型变量。 既然都是整型变量,想要转化成数组下标就不难实现了。最简单的转化方式是:按照数组长度进行取模运算。 index = HashCode (Key) % Array.length 实际上,JDK中的哈希函数并没有直接采取取模运算,而是利用了位运算的方式来优化性能。在这里可以简单理解成取模操作。 通过哈希函数,我们可以把字符串或其他类型的key,转化成数组的下标index。 如给出一个长度为8的数组,则当 key = 001121时, index = HashCode ("001121")%Array.length = 1420036703 % 8 = 7

【Nov 10,哈希与并查集】模拟赛题解

陌路散爱 提交于 2020-01-18 02:40:35
学习炜哥,最后再发代码。 No.1 distinct 【问题描述】 陶陶为了给一道平面几何题出数据,需要产生 N 个点(x[i],y[i])。已知 x,y 是由伪随机函数顺序产生,即: X[i+1] = (X[i]*Ax+Bx+i) mod Cx (X[1], Ax,Bx,Cx 是事先给定的) Y[i+1] = (Y[i]*Ay+By+i) mod Cy (Y[1], Ay,By,Cy 是事先给定的) 这样,就可以快速连续产生很多点坐标(X[i], Y[i])。 不幸的是,这样产生的点有可能有相同的,虽然这种几率很少,但严谨的陶陶不允许这种事发生。陶陶要求你帮助他解决最少要产生前多少项时,正好有 N 个不相同的点。 【输入格式】第一行。一个整数 N . 第二行:4 个整数 X[1]、 Ax、Bx、Cx . 第三行:4 个整数 Y[1]、 Ay、By、Cy . 【输出格式】 一个整数 M 。表示最少要连续产生 M 个点,正好有 N 个不相同的点。数据保证有答案。 【数据范围】1<=N<=1,000,000, 其它所有数据都在[1...1,000,000,000]范围内。 【输入样例】21 2 4 3 6 5 2 3 13 【输出样例】 24 很单纯的Hash。将求出的x与y分别成一个大质数,加起来模一个大质数即可。 No.2 Allbarns 【题目描述】

《Python编程从入门到实战》基础知识

笑着哭i 提交于 2020-01-18 02:18:42
1、列表解析 列表解析将for循环和创建新元素的代码合并成一行,并自动附加新元素。 squares = [ value ** 2 for value in range ( 1 , 9 ) ] print ( squares ) 2、range(start,stop,step) 其中第三参数为步长,start若不设置,则缺省为0,step若不设置,缺省值为1. 3、在python3中正常输出汉字 在前面加上u print ( u "汉字测试" ) 4、列表切片 #列表名[start:stop] #注意!中间是冒号 其中start是其实索引,stop为终止索引。如想取出列表List1[]中的第2-4个元素,则应写为List1[1:4],这样可取出索引为1,2,3的元素 注意 终止索引4对应的元素并不能取到,而可取到的最后元素为其 5、元组 列表是可以修改的,常用于存储收集可变化的数据集。有时需要创建一系列不可修改的元素,元组可以满足这种需求。不可变的列表称为元组。 ·元组定义 元组看起来像列表,但用圆括号标志,不用方括号标识。虽然元组的元素不可修改,但存储元组的变量可以重新赋值。如果需要存储的值在程序的整个生命周期内都不变,可使用元组。 #可以这样修改元组的值,可自行print一下验证 square = ( 10 , 20 ) square = ( 5 , 10 )

java集合框架

喜夏-厌秋 提交于 2020-01-18 02:00:38
在此之前的Java2, Java 提供特设课程,如字典,向量,堆栈和属性(Dictionary, Vector, Stack,Properties)来存储和处理的对象组。虽然这些类是非常有用的,他们缺乏一个中心,统一的主题。因此,所使用的矢量的方式是从使用属性的方式不同。 集合框架的目的是要满足几个目标。 框架必须是高性能的。在实现了基本的集合(动态数组,链表,树,哈希表)是高效的。 框架具有允许不同类型的集合以类似的方式和高度的互操作性。 扩展和/或适应的集合必须是容易的。 为此,整个集合框架是围绕一组标准的接口设计。提供了几种标准的实现,例如LinkedList,HashSet和TreeSet,这些接口,可以按原样使用,也可以实现自己的集合。 一个集合框架是一个统一的体系结构来表示和操作集合。所有集合框架包含以下内容: 接口: 这些都是表示集合的抽象数据类型。接口允许其代表性细节的集合可以独立操作。在面向对象的语言,接口一般形成了一个等级。 实现,即类: 这些都是集合接口的具体实现。在本质上,它们是可重复使用的数据结构。 算法: 这些是执行有用的计算的方法,例如搜索和排序,在该实施集合接口的对象。说是多态的算法:也就是说,同样的方法可以在许多不同的适当的集合接口的实现中使用。 除了集合该框架定义了几个映射的接口和类。映射存储键/值对。虽然映射是不是在正确使用的术语集合

LeetCode205----同构字符串

独自空忆成欢 提交于 2020-01-17 16:41:23
给定两个字符串 s 和 t ,判断它们是否是同构的。 如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。 所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。 示例 1: 输入: s = "egg", t = "add" 输出: true 示例 2: 输入: s = "foo", t = "bar" 输出: false 示例 3: 输入: s = "paper", t = "title" 输出: true 说明: 你可以假设 s 和 t 具有相同的长度。 思路: 我们拿 "paperp" 和 "titlel" 举例: (1)首先我们会定义一个哈希表(Map)来完成一种一一对应的关系,第一次进来时我们把p和t对应 p <==> t (2)这时我们继续判断下一个字符a和i,我们在哈希表中并没有找到以a为key的项,并且t作为value也并没有出现在其他项中,所以我们添加a t键值对 p <==> t a <==> i (3)继续,我们又找到了p字符和t字符,我们可以在哈希表中找到以p为key的项,并且value是t,而我们此时遍历到的确实是t,代表匹配上了,继续下一个 (4)拿到e和l字符,哈希表没有以e为key的项,并且l也没有作为value出现在其他项内,所以添加键值对 p <==> t a <==> i

查找三 哈希表的查找

馋奶兔 提交于 2020-01-16 10:45:59
目录 要点 哈希表和哈希函数 在记录的存储位置和它的关键字之间是建立一个确定的对应关系(映射函数),使每个关键字和一个存储位置能 唯一对应 。这个映射函数称为 哈希函数 ,根据这个原则建立的表称为 哈希表(Hash Table) ,也叫 散列表 。 以上描述,如果通过数学形式来描述就是: 若查找关键字为 key ,则其值存放在 f(key) 的存储位置上。由此, 不需比较便可直接取得所查记录 。 注:哈希查找与线性表查找和树表查找最大的区别在于,不用数值比较。 冲突 若 key1 ≠ key2 ,而 f(key1) = f(key2),这种情况称为 冲突 (Collision)。 根据哈希函数f(key)和处理冲突的方法将一组关键字映射到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“像”作为记录在表中的存储位置,这一映射过程称为 构造哈希表 。 构造哈希表这个场景就像汽车找停车位,如果车位被人占了,只能找空的地方停。 构造哈希表 由以上内容可知,哈希查找本身其实不费吹灰之力,问题的关键在于如何构造哈希表和处理冲突。 常见的构造哈希表的方法有 5 种: (1)直接定址法 说白了,就是小学时学过的 一元一次方程 。 即 f(key) = a * key + b。其中,a和b 是常数。 (2)数字分析法 假设关键字是R进制数(如十进制)。并且哈希表中

数据结构-哈希表

旧时模样 提交于 2020-01-16 01:46:58
哈希表结构   在python中,常见的两种基础数据结构字典和集合都是用哈希表实现的   哈希表是一个通过哈希函数来计算数据存储位置的数据结构   通常支持以下操作: 插入键值对 insert(key,value) 根据键获取值 get(key) 删除键值对 delete(key) 直接寻址表   把key为k的元素放到下标为k的位置上   直接寻址技术存在以下缺点: 当域U很大时,需要消耗大量内存 U很大而实际出现的key很少,会浪费大量的空间 无法处理关键字不是数字的情况   改进直接寻址表:+哈希函数 = 哈希表 构建大小为m的寻址表T key为k的元素放到h(k)的位置上 h(k)就是一个哈希函数,将域U映射到表T[0,..m-1]上 哈希表(Hash Table)   又称散列表,是一种线性表的存储结构,哈希表由一个直接寻址表和一个哈希函数组成   哈希函数h(k)将元素关键字K作为自变量,返回元素的存储下标 哈希冲突   由于哈希表的大小是有限的,而要存储的值的数量是无限的因此对于任何哈希函数,都会出现两个不同元素映射到同一个位置上的情况,这种情况叫做哈希冲突   比如h(k) = k % 7, 0,7,14都会映射到同一位置   解决哈希冲突方式1:开放寻址法   开放寻址法:如果哈希函数返回的位置已经有值,则可以向后探查新的位置来存储这个值   解决哈希冲突方式2

数据结构之哈希、哈希函数、哈希表

被刻印的时光 ゝ 提交于 2020-01-16 01:46:36
什么是哈希? 哈希,也称散列。在某种程度上,散列是与排序相反的一种操作,排序是将集合中的元素按照某种方式比如大小顺序排列在一起,而散列通过计算哈希值,打破元素之间原有的关系,使集合中的元素按照散列函数的分类进行排列。 为什么用哈希? 我们通常使用数组或者链表来存储元素,一旦存储的内容数量特别多,需要占用很大的空间,而且在查找某个元素是否存在的过程中,数组和链表都需要挨个循环比较,而通过 哈希 计算,可以大大减少比较次数。下面举个例子! 现在有 4 个数 {2,5,9,13},需要查找 13 是否存在。 1.使用数组存储,需要新建个数组 new int[]{2,5,9,13},然后需要写个循环遍历查找,这样需要遍历 4 次才能找到,时间复杂度为 O(n)。 2.而假如存储时先使用哈希函数进行计算,这里我随便用个函数: H[key] = key % 3; 四个数 {2,5,9,13} 对应的哈希值为: H[2] = 2 % 3 = 2; H[5] = 5 % 3 = 2; H[9] = 9 % 3 = 0; H[13] = 13 % 3 = 1; 然后把它们存储到对应的位置。 当要查找 13 时,只要先使用哈希函数计算它的位置,然后去那个位置查看是否存在就好了,本例中只需查找一次,时间复杂度为 O(1)。 因此可以发现,哈希 其实是随机存储的一种优化,先进行分类