【LeetCode】146. LRU缓存机制

【LeetCode】146. LRU缓存机制_第1张图片
【LeetCode】146. LRU缓存机制_第2张图片

官方解法:创建一个双向链表,实现这个功能。用一个hashMap来进行映射,判断链表中是否有某个key,并O(1)找到这个node
/**
 * 当缓存容量达到上限时,
 * 它应该在写入新数据之前删除最久未使用的数据值,
 * 从而为新的数据值留出空间。
 */
// 用一个双向链表来解题。用hashMap来查找是否有键值对。
class LRUCache {
    public static void main(String[] args) {
        LRUCache lruCache = new LRUCache(1);
        lruCache.put(2, 1);
        int i = lruCache.get(2);
        System.out.println(i);//1
        lruCache.put(3, 2);
        int i1 = lruCache.get(2);
        System.out.println(i1);//-1

    }

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

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

        Node() {
        }
    }

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

    public LRUCache(int capacity) {
        map = new HashMap<>();
        size = 0;
        head = new Node();
        tail = new Node();
        head.next = tail;
        tail.pre = head;
        this.capacity = capacity;
    }

    public int get(int key) {
        Node node = map.get(key);
        if (node == null) return -1;
        else { // 有这个key
            moveToFirst(node);
            return node.value;
        }
    }

    public void put(int key, int value) {
        Node node = map.get(key);
        if (node == null) { // 进行插入。
            Node newNode = new Node(key, value);
            map.put(key, newNode);
            insertToFirst(newNode);
            size++;
            if (size > capacity) { // 超出了容量。
                int tmp = tail.pre.key;
                map.remove(tmp);
                deleteLast();
                size--;
            }

        } else { // 链表中已经有这个key了。
            node.value = value;
            moveToFirst(node);
        }
    }

    // 删除最后一个结点。
    private void deleteLast() {
        remove(tail.pre);

    }

    // 将一个node,移出来,然后发到头部。
    private void moveToFirst(Node node) {
        remove(node);
        insertToFirst(node);
    }

    // 将一个node插到头部。
    private void insertToFirst(Node node) {
        node.next = head.next;
        node.pre = head;
        head.next.pre = node;
        head.next = node;
    }

    // 将一个node移出
    private void remove(Node node) {
        node.pre.next = node.next;
        node.next.pre = node.pre;
    }

}

你可能感兴趣的:(算法)