菜鸟笔记
提升您的技术认知

面试题

实现一个LRU Cache 算法LRU Cache C++三种解法java实现LRU算法及编码实现LRU策略缓存LRU算法常见缓存算法和LRU的c++实现设计循环双端队列(deque)LRU 缓存结构 (c++ 哈希双链表实现)LRU缓存机制删除单链表中的指定节点Linux 内核经典面试题拼多多社招面经:Redis是重点,讲一讲redis的内存模型线程、进程、协程的区别C++经典面试题面试官:我们只想要这样的C++工程师Linux C/C++ 学习路线链表操作汇总C++11的智能指针面试题浏览器中输入url后发生的事情常用的限流算法HTTP协议和HTTPS协议面试题网络编程面试题目总结c++后台面试题目如何实现LRU算法?如何寻找无序数组中的第K大元素?布隆过滤器 - 如何在100个亿URL中快速判断某URL是否存在?如何实现大整数相加?C++面试题及基本知识点总结C++给定出栈序列判定是否合法消息队列面试题要点redis缓存击穿,失效以及热点key解决方案网页在浏览器上的渲染过程几种限流算法lru算法例题C/C++常见面试知识点总结附面试真题----20210529更新引入MQ消息队列的作用及其优缺点MySQL面试篇社招三年后端面试题60道测开面试题,背完直接涨工资二叉树的层序遍历(两种方法实现)Bitmap 海量数据处理字符串倒序输出的五种方法C语言 输入10个数,统计出并输出正数、负数和0的个数字节三面:如何设计一个高并发系统架构,网络 面试36问,DDos攻击原理C++线程池使用 C++11 编写可复用多线程任务池

LRU缓存机制

阅读 : 2182

代码 

哈希表 + 双链表

class LRUCache {
    //双向链表节点
    private static class DListNode{
        int key;
        int value;
        DListNode prev;
        DListNode next;
        DListNode(){

        }
        DListNode(int key, int value){
            this.key = key;
            this.value = value;
        }
    }
    //缓存的最大容量
    private int capacity;
    //缓存的当前大小
    private int size;
    private DListNode head;
    private DListNode tail;
    //真正的缓存结构
    private Map<Integer, DListNode> cache = new HashMap<>();
    public LRUCache(int capacity) {
        this.size = 0;
        this.capacity = capacity;
        //构造函数中初始化一个有尾结点和头节点的双向链表
        head = new DListNode();
        tail = new DListNode();
        head.next = tail;
        tail.prev = head;
    }
    
    public int get(int key) {
         DListNode dListNode = cache.get(key);
        if(dListNode == null){
            return -1;
        }
        //找到链表节点则将其加入到链表头,并返回链表的节点
        removeNode(dListNode);
        addNodeToHead(dListNode);
        return dListNode.value;
    }
    
    public void put(int key, int value) {
     
        DListNode dnode = cache.get(key);
        if(dnode == null){
            DListNode newNode = new DListNode(key, value);
            cache.put(key, newNode);
            addNodeToHead(newNode);
            //插入成功,大小加一
            size++;
            //超出尺寸,则删除双链表中的最后一个元素结点,并删除该链表元素节点的hashMap中的元素
            if(size > capacity){
                DListNode finalNode = tail.prev;
                removeNode(finalNode);
                //通过链表元素的key找到hashMap中的key并删除
                cache.remove(finalNode.key);
                size--;
            }
        }else{//如果key存在则需要对hashMap的值进行更新,并将双链表节点放到链表头
            // cache.put(key, newNode);
            dnode.value = value;
            removeNode(dnode);
            addNodeToHead(dnode);
        }
    }

    public void removeNode(DListNode dListNode) {
        dListNode.prev.next = dListNode.next;
        dListNode.next.prev = dListNode.prev;
    }

    public void addNodeToHead(DListNode dListNode){
        dListNode.next = head.next;
        head.next.prev = dListNode;
        head.next = dListNode;
        dListNode.prev = head;
    }
}