设计一个HashSet [hash函数 + 存数据的数组 + hash冲突]

前言

hashSet拆分即hash & set,设计hash需要确定hash函数 + 存数据的数组 + hash冲突的解决办法。对于set,hash的key天然的不重复,所以直接用key作为set的元素即保证不重复性。

一、设计hash集合

在这里插入图片描述

二、hash函数+数组+拉链法

1、常规设计

// 设计一个hashSet
public class MyHashSet {
    Node[] table;
    private final static int N = 769;// 取一个质数作为数组长度,减少冲突。

    public MyHashSet() {
        table = new Node[N];
        // 设置头节点,统一操作。
        for (int i = 0; i < N; i++) table[i] = new Node();
    }
    // 三个操作都是:找key映射到的头节点,然后链表寻找是否有对应的key.
    public void add(int key) {
        int h = hash(key);

        Node p = table[h];
        while (p.next != null) {
            // 有此key,就不用再添加了。
            if (key == p.next.key) return;

            p = p.next;
        }
        Node n = new Node();
        n.key = key;

        p.next = n;
    }

    public void remove(int key) {
        int h = hash(key);

        Node p = table[h];
        while (p.next != null) {
            // 有此key,才把其移除掉,并break出去。
            if (p.next.key == key) {
                p.next = p.next.next;

                break;
            }
            p = p.next;
        }
    }

    public boolean contains(int key) {
        int h = hash(key);

        Node p = table[h];
        while (p.next != null) {
            // 找到就返回。
            if (p.next.key == key) return true;

            p = p.next;
        }
        return false;
    }
    // 对key进行扰乱,再对质数取余。
    private int hash(int key) {
        key = (key >>> 16) ^ key;

        return key % N;
    }

    // hash冲突时,用拉链法解决。
    class Node {
        int key;
        Node next;
    }
}

2、常见的数组hash

class MyHashSet {
    final static int N = 1000000;
    int[] fx = new int[N + 1];
    public MyHashSet() {

    }
    
    public void add(int key) {
        fx[key] = 1;
    }
    
    public void remove(int key) {
        // 是1就变0,是0就不管。
        fx[key] = 0;
    }
    
    public boolean contains(int key) {
        return fx[key] == 1;
    }
}

总结

1)hash三要素:hash函数 + 存数据的数组 + hash冲突的解决方式。

2)hash函数有很多,比如线性法/平方法,hash冲突的方式也有很多,拉链法/线性探测法/平方探测法等等,以后算法能力提高了,还可以用红黑树数据结构来解决冲突,降低搜索时间复杂度。

参考文献

[1] LeetCode 设计一个hash集合

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值