LRU缓存

15 阅读1分钟

题目链接

leetcode.cn/problems/lr…

思路

LRU的整个过程就像是把读的书从一堆书中抽出来,放到顶部

首先定义节点,每个点的值包括 key,value ,next , prev

class Node{
    Node prev,next;
    int val,key;
    Node(int k,int v){
        val=v;
        key=k;
    }
}

初始化

    private final int capacity;
    private final Node dummy=new Node(0,0);
    private final Map<Integer,Node>keyToMap=new HashMap<>();

    public LRUCache(int capacity) {
        this.capacity=capacity;
        dummy.prev=dummy;
        dummy.next=dummy;
    }

插入

    public void put(int key, int value) {
        if(keyToMap.containsKey(key)){
            //有书,更新值
            Node node=getNode(key);
            node.val=value;
            return;
        }
        Node node=new Node(key,value);
        keyToMap.put(key,node);
        pushFront(node);
        
        //书太多了
        if(keyToMap.size()>capacity){
            Node backNode=dummy.prev;
            keyToMap.remove(backNode.key);
            remove(backNode);
        }

    }

获取

    public int get(int key) {
        Node node = getNode(key);
        return node != null ? node.val : -1;
    }

    public Node getNode(int key) {
        if (!keyToMap.containsKey(key)) {
            return null;
        } // 判断是否存在
        Node node = keyToMap.get(key);
        // 抽出书
        remove(node);
        // 放在第一位
        pushFront(node);
        return node;

    }

移除

    public void remove(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

放到书堆的顶部

public void pushFront(Node node) {
        node.next = dummy.next;
        node.prev = dummy;
        node.next.prev = node;
        node.prev.next = node;
}