力扣leetcode第146题LRU缓存机制

使用HashMap+双链表的方式实现。

使用HashMap可以在O(1)的时间查询到缓存key,使用双链表是因为插入的时候要在头部插入,删除最少使用的key需要尾部删除。

 

import java.util.HashMap;
import java.util.Map;

class LRUCache {

    /**
     * ["LRUCache","put","put","put","put","get","get","get","get","put","get","get","get","get","get"]
     * [[3],[1,1],[2,2],[3,3],[4,4],[4],[3],[2],[1],[5,5],[1],[2],[3],[4],[5]]
     * @param args
     */
    public static void main(String[] args) {
        LRUCache lRUCache = new LRUCache(3);
        lRUCache.put(1, 1);
        lRUCache.put(2, 2);
        lRUCache.put(3, 3);
        lRUCache.put(4, 4); // 移除【1,1】
        System.out.println(lRUCache.get(4));
        System.out.println(lRUCache.get(3));
        System.out.println(lRUCache.get(2));
        System.out.println(lRUCache.get(1));  //因为被移除了,所以获取不到。
        lRUCache.put(5, 5); // 4被移除。
        System.out.println(lRUCache.get(1));
        System.out.println(lRUCache.get(2));
        System.out.println(lRUCache.get(3));
        System.out.println(lRUCache.get(4));
        System.out.println(lRUCache.get(5));

    }


    public static void main111(String[] args) {
        LRUCache lRUCache = new LRUCache(2);
        lRUCache.put(1, 1); // 缓存是 {1=1}
        lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
        System.out.println(lRUCache.get(1));
        lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
        System.out.println(lRUCache.get(2));
        lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
        System.out.println(lRUCache.get(1));
        System.out.println(lRUCache.get(3));
        System.out.println(lRUCache.get(4));

    }

    //为什么需要使用双链表?因为需要移除最少使用那个元素。插入的时候从头部插入,移除的时候从尾部移除。

    class Node{
        int key;   //这里并不能移除,因为已知Node后,还要根据key去删除map中的数据
        int value;
        Node previous;
        Node next;
        public Node(int key,int value){
            this.key=key;
            this.value=value;
        }
    }

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

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



    private void removeNode(){
        if(head==tail){
            if(tail!=null){
                map.remove(tail.key);
            }
            head=tail=null;
        }else{
            Node temp=tail;
            tail=temp.previous;
            temp.previous.next=null;
            temp.previous=null;
            map.remove(temp.key);
        }
    }

    private void removeNode(Node current){
        int tempKey=current.key;
        if(current==head){
            if(current==tail){
                head=tail=null;
            }else{
                head=current.next;
                current.next.previous=null;
                current.next=null;
            }
        }else if(current==tail){
            if(head==tail){
                head=tail=null;
            }else{
                tail=current.previous;
                current.previous.next=null;
                current.previous=null;
            }
        }else{
            current.previous.next=current.next;
            current.next.previous=current.previous;
            current.next=null;
            current.previous=null;
        }
        map.remove(tempKey);
    }

    private void insertNode(Node newNode){
        if(head==null){
            head=tail=newNode;
        }else{
            newNode.next=head;
            head.previous=newNode;
            head=newNode;
        }
        map.put(newNode.key,newNode);
    }
    private void moveNodeToHead(Node current){
        removeNode(current);
        insertNode(current);
    }
    
    public int get(int key) {
        Node current=map.get(key);
        if(current!=null){
            moveNodeToHead(current);
            return current.value;
        }
        return -1;
    }
    
    public void put(int key, int value) {
        Node current=map.get(key);
        if(current!=null){
            current.value=value;
            moveNodeToHead(current);
        }else{
            //删除最少使用的那个node
            if(map.size()==capacity){
                removeNode();
            }
            //新增一个node,头插法
            Node newNode=new Node(key,value);
            insertNode(newNode);
        }

    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值