Bootstrap

lc 146. LRU 缓存

通过双向链表和哈希表实现

双向链表靠近头部是最近使用的键值对

双向链表靠近尾部是最久未被使用的键值对

哈希表将缓存数据作为key, value为其在双向链表中的位置

首先通过哈希表找到该项在双向链表中的位置,然后将其移动到链表的头部

对于get操作:

首先判断key是否存在,不存在返回-1

如果key存在,通过哈希表找出对应的位置,然后将它移动到头部 

对于put操作:

如果key不存在,使用key和value创建一个新结点并放到头部,然后判断节点是是否超出容量,如果超出容量,则删除链表尾部节点,并删除出哈希表中对应的项

如果key存在,则更新哈希表中的value,并将链表中结点放到头部

class LRUCache {

    //定义双向链表结构

    class Node{

        int key;

        int value;

        Node prev;

        Node next;

        public Node(){key = -1;}

        public Node(int k, int v){

            key = k;

            value = v;

        }

    }

    //定义哈希表和容量以及头尾结点

    private Map<Integer, Node> mp = new HashMap<>();

    private int capacity;

    private Node head, tail;

    //

    public LRUCache(int capacity) {

        this.capacity = capacity;

        head = new Node();

        tail = new Node();

        head.next = tail;

        tail.prev = head;

    }

   

    public int get(int key) {

        if(mp.containsKey(key)){

            Node node = mp.get(key);

            //先删除该结点

            node.prev.next = node.next;

            node.next.prev = node.prev;

            //移动到头部

            moveToHead(node);

            return node.value;

        }else{

            return -1;

        }

    }

   

    public void put(int key, int value) {

        if(mp.containsKey(key)){

            Node node = mp.get(key);

            node.value = value;

            node.prev.next = node.next;

            node.next.prev = node.prev;

            moveToHead(node);

        }else{

            Node node = new Node(key, value);

            mp.put(key, node);

            if(mp.size() > capacity){

                Node delNode = tail.prev;

                mp.remove(delNode.key);

                tail.prev.prev.next = tail;

                tail.prev = tail.prev.prev;

            }

            moveToHead(node);

        }

    }

        private void moveToHead(Node node){

            node.prev = head;

            node.next = head.next;

            head.next.prev = node;

            head.next = node;

        }

}

;