当前位置: 首页 > news >正文

leetcode146.LRU缓存

思路源自

【面试高频】146. LRU 缓存

 采用哈希表+双向链表

put一个键值对时,采用头插法将缓存块置于等级较高的位置,如果put数量超出限制,那么就将尾部的缓存块删除,以此达到置换的一个效果

get一个键值对也是同样的思路,如果不命中直接返回-1,如果命中先删除缓存块再头插缓存块,这样就达到了访问后更新缓存块等级的目的

class LRUCache {

    class DoubleLinkedNode {
        DoubleLinkedNode pre;
        int key;
        int value;
        DoubleLinkedNode next;

        public DoubleLinkedNode() {
            key=-1;
            value=-1;
        }

        public DoubleLinkedNode(int key, int value) {
            this.key=key;
            this.value = value;
        }
    }

    private int size;
    private int capacity;
    private Map<Integer,DoubleLinkedNode> cache;
    DoubleLinkedNode head;
    DoubleLinkedNode tail;

    //初始化两个虚拟节点,头尾指针互指
    public LRUCache(int capacity) {
        this.size=0;
        this.capacity=capacity;
        this.cache = new HashMap<>();
        this.head = new DoubleLinkedNode();
        this.tail = new DoubleLinkedNode();
        head.pre=null;
        head.next=tail;
        tail.pre=head;
        tail.next = null;
    }

    //获取缓存中的值,如果命中要更新缓存
    public int get(int key) {
        if (cache.containsKey(key)) {
            DoubleLinkedNode doubleLinkedNode = cache.get(key);
            this.delete(doubleLinkedNode.key);
            this.add(doubleLinkedNode.key, doubleLinkedNode.value);
            return doubleLinkedNode.value;
        } else {
            return -1;
        }
    }

    //缓存添加或者置换
    public void put(int key, int value) {
        if (cache.containsKey(key)) {
            this.delete(key);
            this.add(key, value);
        } else {
            if (this.capacity == this.size) {
                this.delete(tail.pre.key);
            }
            this.add(key, value);
        }
    }

    //新增一个新的缓存,采用头插法
    private void add(int key, int value) {
        DoubleLinkedNode doubleLinkedNode = new DoubleLinkedNode(key, value);
        doubleLinkedNode.pre=this.head;
        doubleLinkedNode.next=this.head.next;
        this.head.next.pre=doubleLinkedNode;
        this.head.next=doubleLinkedNode;
        this.size++;
        cache.put(key, doubleLinkedNode);
    }

    //删除一个现有缓存
    private void delete(int key) {
        DoubleLinkedNode doubleLinkedNode = cache.get(key);
        doubleLinkedNode.pre.next=doubleLinkedNode.next;
        doubleLinkedNode.next.pre = doubleLinkedNode.pre;
        this.size--;
        cache.remove(key);
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

相关文章:

  • 全球消费理性化浪潮下:跨境电商品牌溢价体系面临重构
  • 深入解析异构计算:从原理到 C++ 实践
  • ubuntu22.04 如何安装 ch341 驱动
  • MySQL-触发器
  • QT基础:安装与简介
  • Unity插件SuperScrollView详解
  • 端到端语音识别案例
  • Docker部署sprintboot后端项目
  • Android 系统中,应用申请的权限相关信息介绍
  • 一文详解QT环境搭建:Windows使用CLion配置QT开发环境
  • 深度学习-153-DeepSeek之调用远程大模型API接口和可用的开源Deepseek服务
  • C#实现HTTP服务器:处理文件上传---解析MultipartFormDataContent
  • 26考研——线性表_ 线性表的链式表示_单链表(2)
  • OpenCV 图形API(或称G-API)(1)
  • 周学习总结
  • 本地后台运行redis服务
  • SpringMVC 拦截器(Interceptor)
  • 渗透测试:登录页面的测试-弱口令思路和实战
  • 计算机网络知识汇总
  • 【水印】水印识别的算法方案思考
  • 东营网站建设/网络关键词优化方法
  • 坂田网站建设推广公司/最吸引人的营销广告词
  • 创业网站建设政策/app推广软文范文
  • wordpress做购物网站/学新媒体运营最好的培训学校
  • 自己做的网站怎样赚钱吗/合肥网站排名提升
  • 网站的小图标怎么做的/河南网站seo推广