acwing 840. 模拟散列表-java
题目所属分类
哈希表相关知识
按照解决冲突的方式可以分为开放寻址法和拉链法
注意 这里面取模的那个数 最好是质数 因为这样在数学证明上 这个质数是产生冲突最少的
开放寻址法 一般要开到数据范围的2-3倍 这样冲突会少一些
造成之后的查找异常 不过大多数情况下 哈希表的操作只有查找和插入
哈希表模板
(1) 拉链法
int h[N], e[N], ne[N], idx;
// 向哈希表中插入一个数
void insert(int x)
{
int k = (x % N + N) % N;
e[idx] = x;
ne[idx] = h[k];
h[k] = idx ++ ;
}
// 在哈希表中查询某个数是否存在
bool find(int x)
{
int k = (x % N + N) % N;
for (int i = h[k]; i != -1; i = ne[i])
if (e[i] == x)
return true;
return false;
}
(2) 开放寻址法
int h[N];
// 如果x在哈希表中,返回x的下标;如果x不在哈希表中,返回x应该插入的位置
int find(int x)
{
int t = (x % N + N) % N;
while (h[t] != null && h[t] != x)
{
t ++ ;
if (t == N) t = 0;
}
return t;
}
作者:yxc
链接:https://www.acwing.com/blog/content/404/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
在C++中的memset函数是按照字节来进行初始化的 如果想用0X3f3f3f3f来进行初始化的话
int 有四个字节 那么就需要 0x3f进行初始化 也就是memset(h,0x3f,size of h)
原题链接
维护一个集合,支持如下几种操作:
I x,插入一个数 x
Q x,询问数 x 是否在集合中出现过;
现在要进行 N次操作,对于每个询问操作输出对应的结果。
代码案例:输入样例:
5
I 1
I 2
I 3
Q 2
Q 5
输出样例:
Yes
No
题解
1、拉链法
import java.util.Scanner;
public class Main{
static int N = 100003, idx ;
static int[] h = new int[N];
static int[] e = new int[N];
static int[] ne = new int[N];
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
for(int i = 0 ; i < N ; i ++) h[i] = -1;//需要提前把槽清空 空指针为-1
while(n-- > 0){
String s = scan.next();
if(s.equals("I")){
int a = scan.nextInt();
insert(a);
}else{
int b = scan.nextInt();
if(find(b)) System.out.println("Yes");
else System.out.println("No");
}
}
}
static void insert(int x ){//把大数映射到10的5次方级别
int k = (x % N + N)% N;//这样做是为了让余数是正数
e[idx] = x ;
ne[idx] = h[k];
h[k] = idx ++ ;
}
static boolean find(int x ){
int k = (x % N + N)% N;
for(int i = h[k] ; i != -1 ; i = ne[i]){
if(e[i] == x){
return true;
}
}
return false;
}
}
2、开放寻址法
import java.util.Scanner;
public class Main{
static int N = 200003 ;
static int nulls = 0x3f3f3f3f;//表示不在x的范围内 说明此数不在
//可以用来初始化
static int[] h = new int[N];
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
for(int i = 0 ; i < N ; i ++) h[i] = nulls;//需要提前把槽清空 空指针为-1
while(n-- > 0){
String s = scan.next();
int x = scan.nextInt();
int f = find(x);//两个都需要 所以可以将这个提出来
if(s.equals("I")){
//返回x应该插入的位置
h[f] = x ;
}else{
//返回x的下标
if(h[f] != nulls) System.out.println("Yes");
else System.out.println("No");
}
}
}
static int find(int x ){// 如果x在哈希表中,返回x的下标;如果x不在哈希表中,返回x应该插入的位置
int k = (x % N + N)% N;
while(h[k] != nulls && h[k] != x){//如果不在当前坑位 往下走
k ++ ;
if(k == N) k = 0;//范围遍历到头 在从头遍历一下
}
return k;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)