哈希表学习笔记

哈希表简介

哈希表(Hash Table):也叫散列表。是根据关键码值(key value)直接进行访问的数据结构。

哈希表通过【键 key】和【映射函数 Hash(key)】计算出对应的【值 value】,把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数就叫做【哈希函数(散列函数)】,存放记录的数组叫做【哈希表【散列表】】。
哈希表

哈希函数

哈希函数(Hash Function):将哈希表中的元素的关键键值映射为元素存储位置的函数。

哈希函数是哈希表中最重要的部分。一般来说,哈希函数会满足以下几个条件:

  • 哈希函数应该易于计算,并且尽量使计算出来的索引值均匀分布。
  • 哈希函数计算得到的哈希值是一个固定长度的输出值。
  • 如果hash(Key1)不等于Hash(key2),那么key1、key2一定不相等。
  • 如果Hash(key1)等于Hash(key2),那么key1、key2可能相等,也可能不相等(会发生哈希碰撞)。

哈希冲突

哈希冲突(Hash collision):不同的关键字通过同一个哈希函数得到同一哈希地址。

练习题目

1.存在重复元素

在这里插入图片描述
在这里插入图片描述

class Solution {
    public boolean containsDuplicate(int[] nums) {
        //双重循环O(n^2)
        // for(int i=0;i<nums.length-1;i++){
        //     for(int j=i+1;j<nums.length;j++){
        //         if(nums[i]==nums[j]){
        //             return true;
        //         }
        //     }
        // }
        // return false;

        //排序后相邻比较O(nLogn)
        // Arrays.sort(nums);
        // for(int i=0;i<nums.length-1;i++){
        //     if(nums[i]==nums[i+1]){
        //         return true;
        //     }
        // }
        // return false;

        //使用哈希表O(N)
        Set<Integer> set = new HashSet<Integer>();
        for(int i=0;i<nums.length;i++){
            if(set.contains(nums[i])){
                return true;
            }
            set.add(nums[i]);
        }
        return false;

    }
}

2.存在重复元素 II

在这里插入图片描述
在这里插入图片描述

class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        //双重循环O(N^2)
        // for(int i=0;i<nums.length-1;i++){
        //     for(int j=i+1;j<nums.length;j++){
        //         if(nums[i]==nums[j]&&Math.abs(i-j)<=k){
        //             return true;
        //         }
        //     }
        // }
        // return false;

        //HashMapO(N)
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<nums.length;i++){
            if(map.get(nums[i])!=null&&Math.abs(map.get(nums[i])-i)<=k){
                return true;
            }
            map.put(nums[i],i);
        }
        return false;
    }
}

3.有效的数独

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

class Solution {
    public boolean isValidSudoku(char[][] board) {
        //HashMapO(1),挺呆的这个暴力求
        HashMap<Character,Integer> map = new HashMap<>();
        // 横着
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                char tmp1 = board[i][j];
                if(map.containsKey(tmp1)&&tmp1!='.'){
                    return false;
                }
                map.put(tmp1,1);
            }
            map.clear();
        }
        //竖着
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                char tmp1 = board[j][i];
                if(map.containsKey(tmp1)&&tmp1!='.'){
                    return false;
                }
                map.put(tmp1,1);
            }
            map.clear();
        }
        //小方块
        for(int f1=1;f1<4;f1++){
            for(int f2=1;f2<4;f2++){
                for(int i=3*(f1-1);i<3*f1;i++){
                for(int j=3*(f2-1);j<3*f2;j++){
                    char tmp1 = board[j][i];
                    if(map.containsKey(tmp1)&&tmp1!='.'){
                        return false;
                    }
                    map.put(tmp1,1);
                }
            }
             map.clear();
            }
        }
        return true;
        

        
    }
}

4.两个数组的交集

在这里插入图片描述

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        //双重循环O(n^2)
        // HashSet<Integer> set = new HashSet<Integer>();
        // for(int i=0;i<nums1.length;i++){
        //     for(int j=0;j<nums2.length;j++){
        //         if(nums1[i]==nums2[j]){
        //             //需要去重
        //             set.add(nums1[i]);
        //         }
        //     }
        // }
        // int arr[] = new int[set.size()];
        // int cnt=0;
        // for(Integer num :set){
        //     arr[cnt++]=num;
        // }
        // return arr;

        //使用set集合O(m+n)
        Set<Integer> set1 = new HashSet<Integer>();
        Set<Integer> set2 = new HashSet<Integer>();
        for(Integer num:nums1){
            set1.add(num);
        }
        for(Integer num:nums2){
            set2.add(num);
        }
        return getResult(set1,set2);

    }

    public int[] getResult(Set<Integer> set1,Set<Integer>set2){
        if(set1.size()<set2.size()){
            return getResult(set2,set1);
        }
        //去重
        Set<Integer> set3 = new HashSet<Integer>();
        for(Integer num:set1){
            if(set2.contains(num)){
                set3.add(num);
            }
        }

        //转换为数组
        int[] arr = new int[set3.size()];
        int cnt=0;
        for(Integer num:set3){
            arr[cnt++] = num;
        }
        return arr;

    }
}

5.两个数组的交集 II

在这里插入图片描述

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Map<Integer,Integer> map1 = new HashMap<>();
        Map<Integer,Integer> map2 = new HashMap<>();
        //将数组的值转换到HashMap
        for(Integer num :nums1){
            if(map1.containsKey(num)){
                map1.put(num,map1.get(num)+1);
            }
            else{
                map1.put(num, 1);
            }

        }
        for(Integer num :nums2){
            if(map2.containsKey(num)){
                map2.put(num,map2.get(num)+1);
            }else{
                map2.put(num,1);
            }
            
        }
        return getResult(map1,map2);
    }

    public int[] getResult(Map<Integer,Integer>map1,Map<Integer,Integer>map2){
        
        int cnt=0;
        Map<Integer,Integer> map3 = new HashMap<>();
        for(Integer key:map1.keySet()){
            if(map2.containsKey(key)){
                if(map1.get(key)<map2.get(key)){
                    map3.put(key,map1.get(key));
                }else{
                    map3.put(key,map2.get(key));
                }
            }
        }
        //遍历map3
        for(Integer num :map3.values()){
            cnt+=num;
        }
        int[] arr = new int[cnt];
        int n=0;
        for(Integer num :map3.keySet()){
            int temp = map3.get(num);
            for(int i=0;i<temp;i++){
                arr[n++] = num;
            }
        }

        return arr;

    }
}

6.设计哈希映射

在这里插入图片描述

class MyHashMap {
    private class Pair {
        private int key;
        private int value;

        public Pair(int key, int value) {
            this.key = key;
            this.value = value;
        }

        public int getKey() {
            return key;
        }

        public int getValue() {
            return value;
        }

        public void setValue(int value) {
            this.value = value;
        }
    }

    private static final int BASE = 769;
    private LinkedList[] data;

    //初始化
    public MyHashMap() {
        data = new LinkedList[BASE];
        for(int i=0;i<BASE;i++){
            data[i] = new LinkedList<Pair>();
        }
    }

    
    public void put(int key, int value) {
        int h = hash(key);
        Iterator<Pair> iterator = data[h].iterator();
        while(iterator.hasNext()){
            Pair pair = iterator.next();
            if(pair.getKey()==key){
                pair.setValue(value);
                return;
            }
        }
        data[h].offerLast(new Pair(key,value));

    }
    
    public int get(int key) {
        int h = hash(key);
        Iterator<Pair>iterator = data[h].iterator();
        while(iterator.hasNext()){
            Pair pair = iterator.next();
            if(pair.getKey()==key){
                return pair.value;
            }
        }
        return -1;

    }
    
    public void remove(int key) {
        int h = hash(key);
        Iterator<Pair> iterator = data[h].iterator();
        while (iterator.hasNext()) {
            Pair pair = iterator.next();
            if (pair.key == key) {
                data[h].remove(pair);
                return;
            }
        }


    }
    private static int hash(int key) {
        return key % BASE;
    }
}

/**
 * Your MyHashMap object will be instantiated and called as such:
 * MyHashMap obj = new MyHashMap();
 * obj.put(key,value);
 * int param_2 = obj.get(key);
 * obj.remove(key);
 */

参考资料

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值