leetcode146 LRU缓存

LRU缓存

本题中要求插入数据以及获取数据都需要* O(1)* 的平均时间复杂度运行,因此借用了哈希表和双向链表

其中哈希表用于快速定位节点

双向链表用于维护一个链表来准确找出最近最少使用的节点,具体实现逻辑如下

  1. 假如用户get了该节点,那么在双向链表中删除该节点,然后插入到头节点中,因此尾节点就是最近最少使用的节点
  2. 假如说现在LRU中满了,那么拿出尾节点前面前面的节点删掉即可满足要求
public class LRUCache {

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

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

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

    public int get(int key) {
        if (map.containsKey(key)){
            Node node = map.get(key);
            // 删除然后插入头节点
            removeCache(key);
            // 插入头节点
            insertHead(key,node.value);
            return node.value;
        }else{
            return -1;
        }
    }

    private void insertHead(int key, int value) {
        Node node = new Node(key,value);
        node.next = head.next;
        node.pre = head;
        node.next.pre = node;
        head.next = node;
        this.size++;
        map.put(key,node);
        if (this.size > this.capacity){
            int deletedKey = tail.pre.key;
            removeCache(deletedKey);
        }
    }

    private void removeCache(Integer key) {
        Node node = map.get(key);
        Node pre = node.pre;
        Node nex = node.next;
        pre.next = nex;
        nex.pre = pre;
        this.size--;
        map.remove(key);
    }

    public void put(int key, int value) {
        if (map.containsKey(key)){
            removeCache(key);
            insertHead(key,value);
        }else{
            insertHead(key,value);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值