哈希表

哈希表

為{幸葍}努か 提交于 2020-02-09 11:37:33
C语言哈希表 【1】设计数据结构 (1)哈希表由一个结构体HashTable构成 (2)结构体HashTable由两个元素组成。其一为指针数组(链式存储元素);其二为整型变量(记录元素个数) (3)指针数组类型为HashNode *(哈希节点指针) (4)结构体HashNode由数据域和指针域组成。数据域也是一种结构类型变量,指针域为一个同类型指针,为了实现链式存储。 (5)数据域结构体ElemType由关键码以及其他相关信息组成(在此程序里没有添加) (6)拟定哈希表长度为13 【2】C语言表示数据结构 1 #define M 13 2 typedef int KeyType; 3 typedef struct 4 { 5 KeyType key; 6 //otherinfo; 7 }ElemType; 8 typedef struct _Node 9 { 10 ElemType data; 11 _Node *next; 12 }HashNode; 13 typedef struct 14 { 15 HashNode *table[M]; 16 int len; 17 }HashTable; 【3】函数设计 在设计函数之前,让我们先理解一下基本的逻辑: 哈希表中存储的每个元素都有一个关键码,而每个关键码都可以通过与哈希表的总数取模(当然这个算法可以任意选择)得到一个索引

[每日一题] 128. 青蛙过河(数组、记忆化搜索、递归、剪枝)

喜你入骨 提交于 2020-02-08 18:55:22
文章目录 1. 题目来源 2. 题目说明 3. 题目解析 方法一:哈希表、记忆化搜索、递归解法 方法二:迭代解法 方法三:回溯法+贪心策略+剪枝 1. 题目来源 链接: 前K个高频元 来源:LeetCode 2. 题目说明 一只青蛙想要过河。 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有)。 青蛙可以跳上石头,但是不可以跳入水中。 给定石子的位置列表(用单元格序号升序表示), 请判定青蛙能否成功过河(即能否在最后一步跳至最后一个石子上)。 开始时, 青蛙默认已站在第一个石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格1跳至单元格2)。 如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。 请注意: 石子的数量 ≥ 2 且 < 1100; 每一个石子的位置序号都是一个非负整数,且其 < 2 31 2^{31} 2 3 1 ; 第一个石子的位置永远是0。 示例1: [0,1,3,5,6,8,12,17] 总共有8个石子。 第一个石子处于序号为0的单元格的位置, 第二个石子处于序号为1的单元格的位置, 第三个石子在序号为3的单元格的位置, 以此定义整个数组… 最后一个石子处于序号为17的单元格的位置。 返回 true。即青蛙可以成功过河

以太坊的数据结构(状态树、交易树、收据树)

倾然丶 夕夏残阳落幕 提交于 2020-02-08 18:17:42
文章目录 一、状态树 1. trie 2. Patricia tree(trie) 3. Merkle Patricia tree(trie) 4. Modified Merkle Patricia tree(trie) 5. 账户状态值存储 6. 区块代码分析 二、交易树、收据树 一、状态树 以太坊是基于账户的账本,因此需要进行账户地址和账户状态的映射,如下所示: 我们尝试寻找一种合适的数据结构来完成这个需求: 如果以哈希表的形式保存状态数据,可以非常有效率地查找、更新账户状态数据,但是由于状态数据只保存在区块体中,轻节点难以进行Merkle Proof,因此考虑构建Merkle tree; 如果将账户数据简单组织成Merkle tree,不进行排序,就需要发布所有账户到区块中,保证根哈希一致,但是数量级太大,不可行;如果只发布状态变化的账户,就会导致所有节点的根哈希不一致,无法共识; 如果使用排序的Merkle tree,各个节点的根哈希就会相同,但是增加账户时,需要重构Merkle tree,代价太大。另外Merkle tree不能够快速查找、更新状态数据。因此需要考虑一种新的数据结构Merkle Patricia trie。 1. trie trie是一种字典前缀树,信息检索较为方便。如果有General、Genesis、Go、God、Good这几个单词

Leetcode--哈希、映射(python)

梦想的初衷 提交于 2020-02-06 12:48:16
Excel表列序号 给定一个Excel表格中的列名称,返回其相应的列序号。 例如, A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 ... 示例 1: 输入: “A” 输出: 1 示例 2: 输入: “AB” 输出: 28 示例 3: 输入: “ZY” 输出: 701 解法 其实就是把十进制改成了26进制。 注意把字符转换成整数的方法:ord() 以及’A’的整数值是65 class Solution ( object ) : def titleToNumber ( self , s ) : """ :type s: str :rtype: int """ res = 0 for idx in range ( len ( s ) ) : res = res * 26 + ( ord ( s [ idx ] ) - ord ( 'A' ) + 1 ) return res 四数相加 II 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。 为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间,最终结果不会超过 231

普通数字哈希

风格不统一 提交于 2020-02-06 07:40:10
常见哈希 模拟散列表 维护一个集合,支持如下几种操作: “I x”,插入一个数x; “Q x”,询问数x是否在集合中出现过; 现在要进行N次操作,对于每个询问操作输出对应的结果。 输入格式 第一行包含整数N,表示操作数量。 接下来N行,每行包含一个操作指令,操作指令为”I x”,”Q x”中的一种。 输出格式 对于每个询问指令“Q x”,输出一个询问结果,如果x在集合中出现过,则输出“Yes”,否则输出“No”。 每个结果占一行。 数据范围 1≤N≤105 −109≤x≤109 1.拉链法 # include <iostream> # include <string> # include <algorithm> # include <vector> using namespace std ; const int N = 1e5 + 7 ; //N最好取最大范围最近的质数 int h [ N ] , e [ N ] , ne [ N ] , index ; void insert ( int x ) { int k = ( x % N + N ) % N ; //将数字存入哈希表先取模是因为插入的x有可能是负数再加N转化为正数,最后再求模可能原本是正数 e [ index ] = x ; ne [ index ] = h [ k ] ; //拉链法就是以h[k]为头结点建立点链表 h

算法学习18-两个单链表相交的一系列问题

孤街醉人 提交于 2020-02-06 07:26:42
两个单链表相交的一系列问题 【题目】 在本题中,单链表可能有环,也可能无环。给定两个单链表的头节点 head1和head2,这两个链表可能相交,也可能不相交。请实现一个函数, 如果两个链表相交,请返回相交的第一个节点;如果不相交,返回null 即可。 要求:如果链表1的长度为N,链表2的长度为M,时间复杂度请达到 O(N+M),额外空间复杂度请达到O(1) 【思路】 我们可以把本题分解成三个问题 链表是否有环 解法一:利用哈希表解决问题 从第一个节点开始,如果哈希表中不存在,则把节点插入到哈希表中,如果存在的话,则此节点就是最后所求的节点。 解法二:不用哈希表解决问题(这是一个数学问题) 用两个指针,一个快指针,一个慢指针同时从单链表头部开始遍历,一快一慢: 若无环,肯定快指针先遍历到null,此时单链表无环. 若单链表有环,这两个指针肯定在环中相遇,相遇时,让快指针从头head开始遍历,然后放慢速度跟慢指针一样快,两个继续同时向下遍历,直到相遇,此时就是单链表入环节点。 两个链表是否相交,相交的第一个节点是在什么位置 两个无环单链表是否相交 解法一:利用哈希表解决问题 1.把链表一中所有的节点放到哈希表中 2.遍历第二个链表,每个元素在map中是否存在,第一个存在的节点即为相交的第一个节点,如果到达最后都没有的话,及两个链表中不存在链表。 解法二:不利用哈希表解决问题 1

【哈希】Gym - 102448 - C - Call from Mendes

强颜欢笑 提交于 2020-02-05 00:04:33
题目链接 http://codeforces.com/gym/102448/problem/C 题意 三种操作,一共有 Q Q Q 个: 1    X 1\;X 1 X :在字典里插入字符串 X X X 2    X 2\;X 2 X :在字典里删除字符串 X X X 3    X 3\; X 3 X :输出字典中最短的且前缀是 X X X 的下标。如果有多个字符串,输出字典序最小的。 字符串的下标是指该串被插入时的时间。 输入中所有的字符串长度和不超过 1 0 6 10^6 1 0 6 题解 第一眼感觉是可持久化AC自动机?不会啊。然后就看到了这个条件:所有的字符串长度和不超过 1 0 6 10^6 1 0 6 ,决定乱搞。 对每个长度开一个 m a p < h a s h , s e t > [ i ] map<hash, set>[i] m a p < h a s h , s e t > [ i ] ,表示存在一个 s e t set s e t 的字符串满足长度为 i i i 的前缀哈希值是 h a s h hash h a s h 。 s e t set s e t 里记录一下字符串的信息,比如长度啊,字典序啊,下标啊。这个字典序我的求法就比较夸张,直接全部读进来,离散排个序。 然后三种操作只要对应的把 m a p map m a p 和 s e t set s e t

Redis的五种数据类型---String, Hash, List, Set, Zset

会有一股神秘感。 提交于 2020-02-04 23:39:56
前言 Redis有五种数据类型: String, Hash, List, Set, Zset,下面对对这几种类型作详细的介绍 一. String (相当于Java中的字符串) 1.1简介: string 是redis最基本的类型,一个key对应一个value string类型是二进制安全的,意思是redis的string可以包含任何数据。比如jpg图片或者序列化对象。 string 类型是Redis最基本的数据类型,一个键最大能存储512MB 二进制安全是指,在传输数据时,保证二进制数据的信息安全,也就是不被篡改,破译等。如果被攻击,能够及时检测出来。 二进制安全特点: <1>编码,解码发生在客户端完成,执行效率高 <2>不需要频繁的编解码,不会出现乱码 1.2 String命令: (命令不用区分大小写) 赋值语法: [1] Redis set 命令常用于设置key的值,如果key已存储值,set 就是写旧值,且无视类型 set key_name value [2] 只有在key不存在时设置key的值。 Setnx(SET if Not exists) 命令在指定的key不存在时,为key设置指定的值 setnx key value //(面试问题) 解决分布锁的方案之一 [3] 同时设置一个或多个key-value对 mset key value [key value....]

leetcode(六)

跟風遠走 提交于 2020-02-04 20:22:21
字符串中的第一个唯一字符 //利用哈希表来进行操作 class Solution { public int firstUniqChar ( String s ) { HashMap < Character , Integer > count = new HashMap < Character , Integer > ( ) ; int n = s . length ( ) ; // build hash map : character and how often it appears for ( int i = 0 ; i < n ; i ++ ) { char c = s . charAt ( i ) ; //返回指定索引处的字符 count . put ( c , count . getOrDefault ( c , 0 ) + 1 ) ; } // find the index for ( int i = 0 ; i < n ; i ++ ) { if ( count . get ( s . charAt ( i ) ) == 1 ) return i ; } return - 1 ; } } 哈希表还得继续学 算法的思路就是遍历一遍字符串,然后把字符串中每个字符出现的次数保存在一个散列表中。这个过程的时间复杂度为 O(N),其中 N 为字符串的长度。

REDIS 字典数据结构

淺唱寂寞╮ 提交于 2020-02-04 20:10:13
对于REDIS来讲 其实就是一个字典结构,key ---->value 就是一个典型的字典结构 【当然 对于vaule来讲的话,有不同的内存组织结构 这是后话】 试想一个这样的存储场景: key:"city" value:"beijing" 如果有若干个这样的键值对,你该怎么去存储它们呢 要保证写入和查询速度非常理想~! 抛开redis不说,如果你想要存储 快速查找的话, Hash算法是最快的,理想的哈希函数可以带来O(1)的查找速度,你都这样想,那么redis也的确采用这种方法来做~! 但是HASH算法有2个致命的弱点:1)填充因子不能太满 2)不好的HASH算法可能会导致一个冲突率非常高。 填充因子不能太满 这个理论上一般为0.5左右 过高 就是哈希槽都被塞满了 ,即使在好的哈希分布算法 也无法避免key冲突。 不好的哈希分布算法 丢到第一个因素来讲, 如果一个不好的哈希分布算法会导致了key分布不均匀,也就是通过哈希函数计算出来的哈希槽都是落在了一个桶里,这样的哈希分布算法是最不理想的,最理想的情况下是 保证每个key都落在不同的哈希槽里【哈希槽>key】 实际存储的哈希存储设计 1)一般来讲,哈希分布函数确定后,可调控的因子就是这个填充因子 如果填充因子大于你卡的某个阈值,那么你就要做哈希结构迁移工作,迁移到一个更大的哈希槽中。而对用同用的这种哈希分布 函数