LRU缓存

88 阅读1分钟

146. LRU 缓存

  • 根据题意要求O1复杂度获取元素,则考虑hash表
  • 而当容量满了,要移出最久未被使用的,因此考虑双向链表
  • 综上其实就是让我们设计一个哈希双向链表

第一步:构造节点

class Node{
        private int key,val;
        Node pre,next;
        public Node(int key,int val){
            this.key=key;
            this.val=val;
        }
    }

第二步:构造双向链表

class DoubleList{
        Node head=new Node(0,0),tail=new Node(0,0);
        int size=0;

        public DoubleList(){
            head.next=tail;
            tail.pre=head;
        }
        public void addFirst(Node node){
            Node temp=head.next;
            head.next=node;
            node.pre=head;
            node.next=temp;
            temp.pre=node;
            size++;
        }
        public void remove(Node node){
            node.pre.next=node.next;
            node.next.pre=node.pre;
            size--;
        }
        public Node removeLast(){
            Node last=tail.pre;
            remove(last);
            return last;
        }
        public int size(){
            return size;
        }
    }

将哈希表与双向链表相结合

    private Map<Integer,Node> hashMap;
    private DoubleList cache;
    private int capacity;
    public LRUCache(int capacity) {
        this.hashMap=new HashMap<>();
        this.cache=new DoubleList();
        this.capacity=capacity;
    }   
    
    public int get(int key) {
        if(!hashMap.containsKey(key)){
            return -1;
        }else{
            int val=hashMap.get(key).val;
            put(key,val);
            return val;
        }
    }
    
    public void put(int key, int value) {
        Node node=new Node(key,value);
        if(hashMap.containsKey(key)){
            cache.remove(hashMap.get(key));
            cache.addFirst(node);
            hashMap.put(key,node);
        }else{
            if(cache.size()==capacity){
                Node last=cache.removeLast();
                hashMap.remove(last.key);
            }
            cache.addFirst(node);
            hashMap.put(key,node);
        }
    }