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;
        
    }
}
posted @   依嘫  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示