第三章 散列表代码实现

3.1 hashcode和equals

hashTable java 代码(非常重要)

hashCode

定义:jdk根据对象的地址或者字符串或者数字算出来的int类型的数值

和equals进行比较

dfdsf

3.2 链接法代码(hash非常重要的部分)

算是小型的设计题

底层的hashMap是由数组和链表来实现的,就是上面说的拉链法。首先当插入的时候,会根据key的hash值然后计算出相应的数组下标,计算方法是index = hashcode%table.length,(这个下标就是上面提到的bucket),当这个下标上面已经存在元素的时候那么就会形成链表,将后插入的元素放到尾端,若是下标上面没有存在元素的话,那么将直接将元素放到这个位置上。
当进行查询的时候,同样会根据key的hash值先计算相应的下标,然后到相应的位置上进行查找,若是这个下标上面有很多元素的话,那么将在这个链表上一直查找直到找到对应的元素。

3-3 开放定址法代码实现 (19:01)

3-4 HashTable 源码分析 (18:06)

3-5 HashMap 源码分析 (43:44)

3-6 HashSet 源码分析 (08:26)

3-7 LinkedHashMap 简介

百度CTO王海峰:百度地图已成为AI时代刻画真实世界的重要基础设施
双向指针

如果面试中出现linkedhashmap,比如题目:LRU leetcode 146 这种题目在design设计题中经常出现的

LinkedHashMap
1、继承hashMap hashmap+linkedlist
2、Entry before, after;
3、有顺序/遍历按照先后插入输出
LinkedHashMap是Hash表和链表的实现,并且依靠着双向链表保证了迭代顺序是插入的顺序。

3-8 Leetcode 实战练习题(待完成)

非常重要的一道题,背都要背下来
设计题的中的大类的一个小类
凡是涉及到O(1)基本都是HashMap

当写put和get时候,永远要当空,从put开始写

put
之前有
之前没有

没满
第一个
非第一个

设计题一般都是难度为medium的题型,不是很难

public class LRUCache {
    class Node {
        int key;
        int value;
        Node next;
        Node pre;

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

    private HashMap<Integer, Node> map;
    private int capacity;
    private Node head;
    private Node tail;

    public LRUCache(int capacity) {
        map = new HashMap<>();
        this.capacity = capacity;
        head = null;
        tail = null;
    }

    public int get(int key) {
        Node node = map.get(key);
        if (node == null) {
            return -1;
        }
        if (node != tail) {
            if (node == head) {
                head = head.next;
            } else {
                node.pre.next = node.next;
                node.next.pre = node.pre;
            }
            tail.next = node;
            node.pre = tail;
            node.next = null;
            tail = node;
        }
        return node.value;
    }
    code modify
    public void put(int key, int value) {
        Node node = map.get(key);
        if (node != null) {
            node.value = value;
            if (node != tail) {
                if (node == head) {
                    head = head.next;
                } else {
                    node.pre.next = node.next;
                    node.next.pre = node.pre;
                }
                tail.next = node;
                node.pre = tail;
                node.next = null;
                tail = node;
            }

        } else {
            Node newNode = new Node(key, value);
            if (capacity == 0) {
                Node temp = head;
                head = head.next;
                temp.next = null;
                map.remove(temp.key);
                capacity++;
            }
            if (head == null && tail == null) {
                head = newNode;
            } else {
                tail.next = newNode;
                newNode.pre = tail;
                newNode.next = null;
            }
            tail = newNode;
            map.put(key, newNode);
            capacity--;
        }
    }
}

3-9 Bloom Filter 布隆过滤器

判断一个元素在集合中的有无:HashSet
如果数据量特别大?
答:位运算方法

新的算法-》布隆过滤器(Bloom Filter)
让每一个字符通过k个hash fucntion并在对应位置置为1
判断每个位置是否为1,如果为1,则认为存在于这个集合中,如果有一个不为1,则认为一定不再这个集合中
缺点:存在一定的误差

3-10 Bloom Filter 布隆过滤器代码实现

不支持remove

解决方法:利用计数排序

3-11 做题须知

HashMap / HashSet :
get() & put)() 的时间复杂度:O(1)
containsKey(value)的时间复杂度:O(1)
containsValue is O(n)
because without the key it doesn't know where it is and the algorithm has to go over all the values stored in the map.

猜你喜欢

转载自www.cnblogs.com/andrewcao95/p/di-san-zhang-san-lie-biao-dai-ma-shi-xian.html