1、题目描述
维护一个集合,支持如下几种操作:
- “I x”,插入一个数x;
- “Q x”,询问数x是否在集合中出现过;
现在要进行N次操作,对于每个询问操作输出对应的结果。
输入格式
第一行包含整数N,表示操作数量。
接下来N行,每行包含一个操作指令,操作指令为”I x”,”Q x”中的一种。
输出格式
对于每个询问指令“Q x”,输出一个询问结果,如果x在集合中出现过,则输出“Yes”,否则输出“No”。
每个结果占一行。
数据范围
1≤N≤1051≤N≤105
−109≤x≤109−109≤x≤109输入样例:
5 I 1 I 2 I 3 Q 2 Q 5
输出样例:
Yes No
2、 分析
使用数组hash[k]和单链表来维护哈希表,每一个数组元素都挂一个单链表,初始化-1代表单链表为空。
3、代码
(1)拉链法
import java.util.*;
import java.io.*;
public class Main{
static int N = 100003; //质数
static int[] h = new int[N];
//单链表
static int[] e = new int[N];
static int[] ne = new int[N];
static int idx;
static void insert(int x){
//先经过哈希函数,找到在数组中的位置
int k = (x % N + N) % N;
//每个数组结点下挂一个单链表,插入到单链表中,头插
e[idx] = x;
ne[idx] = h[k]; //ne[idx] = -1
h[k] = idx;
idx ++;
}
static boolean find(int x){
int k = (x % N + N) % N;
//遍历链表
for(int i = h[k]; i != -1;){
if(e[i] == x) return true;
i = ne[i];
}
return false;
}
public static void main(String[] args){
Scanner in = new Scanner(new InputStreamReader(System.in));
int n = Integer.parseInt(in.nextLine());
//初始化h[k]=-1
Arrays.fill(h, -1);
while(n -- > 0){
String line = in.nextLine();
String[] arr = line.split(" ");
int x = Integer.parseInt(arr[1]);
if("I".equals(arr[0])) {
insert(x);
}else {
boolean flag = find(x);
if(flag) System.out.println("Yes");
else System.out.println("No");
}
}
}
}
(2)开放寻址法
package cn.acwing.数据结构;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Scanner;
/**
* 开放寻址法
* @author zhou
*
*/
public class 模拟散列表 {
static int N = 300003;
static int[] hash = new int[N];
//若x在哈希表,k返回得是x得下标;若x不在,k返回得是x应该存放得位置
static int find(int x){
int k = (x % N + N) % N;
while(hash[k] != -1 && hash[k] != x){
k ++;
if(k == N-1) k = 0;
}
return k;
}
public static void main(String[] args) {
Scanner in = new Scanner(new InputStreamReader(System.in));
int n = Integer.parseInt(in.nextLine());
//初始化h[k]=-1
Arrays.fill(hash, -1);
while(n -- > 0){
String line = in.nextLine();
String[] arr = line.split(" ");
int x = Integer.parseInt(arr[1]);
int k = find(x);
if("I".equals(arr[0])) {
hash[k] = x;
}else {
if(hash[k] == x) System.out.println("Yes");
else System.out.println("No");
}
}
}
}