LeetCode-146. LRU 缓存

目录

    • LRU理论
    • 题目思路
    • 代码实现一
    • 代码实现二

题目来源
146. LRU 缓存

LRU理论

LRU 是 Least Recently Used 的缩写,这种算法认为最近使用的数据是热门数据,下一次很大概率将会再次被使用。而最近很少被使用的数据,很大概率下一次不再用到。当缓存容量的满时候,优先淘汰最近很少使用的数据。

假设现在缓存内部数据如图所示:
这里我们将列表第一个节点称为头结点,最后一个节点为尾结点。(可以想象成队列)
在这里插入图片描述

当调用缓存获取 key=1 的数据,LRU 算法需要将 1 这个节点移动到头结点,其余节点不变
在这里插入图片描述

然后我们插入一个 key=8 节点,此时缓存容量到达上限,所以加入之前需要先删除数据。由于每次查询都会将数据移动到头结点,未被查询的数据就将会下沉到尾部节点,尾部的数据就可以认为是最少被访问的数据,所以删除尾结点的数据。
在这里插入图片描述
然后我们直接将数据添加到头结点。
在这里插入图片描述
这里总结一下 LRU 算法具体步骤:

  • 新数据直接插入到列表头部
  • 缓存数据被命中,将数据移动到列表头部
  • 缓存已满的时候,移除列表尾部数据。

题目思路

实现本题的两种操作,需要用到一个哈希表和一个双向链表。

代码实现一

继承java自带的LinkedHashMap

class LRUCache extends LinkedHashMap<Integer,Integer>{

    private int capacity;

    public LRUCache(int capacity) {
        super(capacity,0.75F,true);
        this.capacity = capacity;
    }
    
    public int get(int key) {
        return super.getOrDefault(key,-1);
    }
    
    public void put(int key, int value) {
        super.put(key, value);
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
        return size() > capacity; 
    }
}

/**
 * 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);
 */

在这里插入图片描述

代码实现二

class LRUCache {
    class Node{
        private int key,val;
        private Node pre,next;

        private Node(int k,int v){
            this.key = k;
            this.val = v;
        }
    }

    class DoubleList{
        // 头尾虚节点
        Node head = new Node(0,0);
        Node tail = new Node(0,0);
        int size;

        //初始化链表
        private DoubleList(){
            head.next = tail;
            tail.pre = head;
            size = 0;
        }

        //头插入
        void addFirst(Node n){
            head.next.pre = n;
            n.next = head.next;
            n.pre = head;
            head.next = n;
            size++;
        }

        //删除链表的某一个元素
        void remove(Node n){
            n.pre.next = n.next;
            n.next.pre = n.pre;
            size--;
        }

        //删除尾结点,并返回该节点
        Node removeLast(){
            Node res = tail.pre;
            remove(res);
            return res;
        } 
    
    }



    HashMap<Integer,Node> map;
    DoubleList cache;
    int cap; //容量

    public LRUCache(int capacity) {
        map = new HashMap();
        cache = new DoubleList();
        this.cap = capacity;
    }
    
    public int get(int key) {
        if(!map.containsKey(key)){  //该节点不存在
            return -1;
        }
        Node res = map.get(key);
        cache.remove(res);
        cache.addFirst(res);
        return res.val;
        
    }
    
    public void put(int key, int value) {
        Node n = new Node(key,value);
        if(map.containsKey(key)){  //若该节点已经存在
            cache.remove(map.get(key));
        }else if(map.size() == cap){  //该节点不存在,但是cache已满
            Node last = cache.removeLast();
            map.remove(last.key);
        }
        cache.addFirst(n);
        map.put(key,n);
    }
}

/**
 * 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);
 */

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/7348.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

把ChatGPT接入我的个人网站

效果图 详细内容和使用说明可以查看我的个人网站文章 把ChatGPT接入我的个人网站 献给有外网服务器的小伙伴 如果你本人已经有一台外网的服务器&#xff0c;并且页拥有一个OpenAI API Key&#xff0c;那么下面就可以参照我的教程来搭建一个自己的ChatGPT。 需要的环境 Cento…

大数据分析工具Power BI(三):导入数据操作介绍

导入数据操作介绍 进入PowBI,弹出的如下页面也可以直接关闭,在Power BI中想要导入数据需要通过Power Query 编辑器,Power Query 主要用来清洗和整理数据。

Go分布式爬虫笔记(十七) 4月Day1

文章目录17 协程线程与协程对比调度方式调度策略栈大小上下文切换速度GMP调度循环调度算法如果本地运行队列已经满了&#xff0c;无法处理全局运行队列中的协程怎么办&#xff1f;查找协程的先后顺序主动调度被动调度抢占调度执行时间过长的抢占调度陷入到系统调用中的抢占调度…

leetcode:颠倒二进制位(详解)

前言&#xff1a;内容包括&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路及图示 题目&#xff1a; 颠倒给定的 32 位无符号整数的二进制位。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;如 Java&#xff09;中&#xff0c;没有无符号整数类型。…

ThreeJS-聚光灯物体投影(二十)

聚光灯&#xff08;灯泡&#xff09; 关键代码&#xff1a; //直线光&#xff08;由光源发出的灯光&#xff09; // const directionalLight new THREE.DirectionalLight(0xFFFFFF, 0.7); // directionalLight.position.set(10, 10, 10); …

【蓝桥杯冲刺】蓝桥杯12届省赛C++b组真题-编程题

目录 试题F&#xff1a;时间显示 解题思路 代码 试题G&#xff1a;砝码称重 解题思路 代码 试题H&#xff1a;杨辉三角 解题思路 代码 试题I&#xff1a;双向排序 解题思路 试题J&#xff1a;括号序列 解题思路 试题F&#xff1a;时间显示 【问题描述】 小蓝要和…

Linux总结(二)

基础IO 1.什么叫文件? 我们需要在操作系统的角度理解文件。 文件 = 文件内容 + 属性(所以即使是空文件,也会占空间,因为我们是需要保存文件属性的,属性也是数据,所以占空间) C/C++程序默认会打开三个文件流,叫做标准输入(stdin),标准输出(stdout),标准错误(std…

【新2023Q2押题JAVA】华为OD机试 - 服务依赖

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:服务依赖 题目 在某系统中有…

时间序列的迁移学习

目录 时间序列及其研究状况&#xff1a; 时间序列中存在迁移学习问题吗&#xff1f; 已有的时间序列建模方法的大致思路 迁移学习如何应用于时间序列建模&#xff1f; 本内容摘录于王晋东老师的《迁移学习导论》 时间序列及其研究状况&#xff1a; 所谓时间序列&#…

Linux权限提升—内核、SUID、脏牛等提权

Linux权限提升—内核、SUID、脏牛等提权1. 前言2. 基础信息收集2.1. 内核、操作系统、设备信息等2.2. 用户信息2.3. 用户权限信息2.4. 环境信息2.5. 进程与服务2.6. 安装的软件2.7. 服务与插件2.8. 计划任务2.9. 是否有存放明文密码2.10. 查看与主机通信信息2.11. 日志信息3. 脚…

基于混合整数规划方法的微网电池储能容量优化配置

代码相关资源&#xff1a;TOPSIS法&#xff08;优劣解距离法&#xff09; 风电场风速两参数weibull(威布尔)分布的MATLAB小程序 遗传算法优化神经网络&#xff0c;对光伏出力预测的优化设计&#xff0c;实现了部分功能 关键词&#xff1a;储能容量优化 储能配置 微网 编程…

10年花费9773亿,华为完成13000颗元器件国产替代,外媒:结束了

近期&#xff0c;华为的消息层出不穷&#xff0c;就在前几天&#xff0c;华为就释放出2个信号&#xff0c;任正非为代表的巨头纷纷表态及发言&#xff0c;显而易见的是&#xff0c;如今华为正处于生死攸关的重要阶段。那么华为释放了哪2个信号呢&#xff1f;其一是&#xff0c;…

centos7离线安装docker

前言 在没有互联网的情况下想要安装某些软件用docker是十分方便的一种方式&#xff0c;例如oracle。原生的oracle安装是非常麻烦的&#xff0c;本人亲眼目睹一个专门搞oracle的公司的人安装oracle三天没有成功&#xff01;因此不得不学习在没有互联网的情况下使用docker来安装…

网络层IP协议和数据链路层

目录IP协议协议头格式分片网段划分特殊的IP地址IP地址的数量限制NAT技术NAT技术背景NAT IP转换过程NAPTNAT技术的缺陷NAT和代理服务器私有IP地址和公网IP地址路由路由表生成算法数据链路层认识以太网以太网帧格式认识MAC地址对比理解MAC地址和IP地址认识MTUMTU对IP协议的影响MT…

web自动化测试:Selenium+Python基础方法封装(建议收藏)

01、目的 web自动化测试作为软件自动化测试领域中绕不过去的一个“香饽饽”&#xff0c;通常都会作为广大测试从业者的首选学习对象&#xff0c;相较于C/S架构的自动化来说&#xff0c;B/S有着其无法忽视的诸多优势&#xff0c;从行业发展趋、研发模式特点、测试工具支持&…

SpringCloud学习2(Spring Cloud Netflix)负载均衡Ribbon、Feign负载均衡、Hystix服务熔断

文章目录负载均衡RibbonRibbon的作用代码实现生产者cloud1_provider实现配置文件在HiController中编写以下代码启动集群消费者cloud1_consumer实现引入依赖编写配置文件编写启动类&#xff0c;并给RestTemplate配置LoadBalanced注解编写RestController来测试Feign负载均衡简介F…

信息收集与运用

目录 一.实验目的 二.实验原理 三.实验内容 一.收集信息 二.猜解密码 三.密码强度检测 源码 测试用例 程序输出结果​编辑 ​四.小结与讨论 1.举出保护个人敏感信息的方法&#xff08;最少三点&#xff09;。 2.如何提高你的密码强壮性&#xff0c;以避免黑客利用密…

Java类加载过程面试总结

什么是Java的类加载机制 Java 虚拟机一般使用 Java 类的流程为&#xff1a;首先将开发者编写的 Java 源代码&#xff08;.java文件&#xff09;编译成 Java 字节码&#xff08;.class文件&#xff09;&#xff0c;然后类加载器会读取这个 .class 文件&#xff0c;并转换成 jav…

05.List的介绍

1. List 在集合框架中&#xff0c;List是一个接口&#xff0c;继承自Collection。 Collection也是一个接口&#xff0c;该接口中规范了后序容器中常用的一些方法&#xff0c;具体如下所示&#xff1a; Iterable也是一个接口&#xff0c;表示实现该接口的类是可以逐个元素进行遍…

仿真与测试:单元测试与Test Harness

本文描述单元测试的概念&#xff0c;以及Test Harness建立的方法和简单的单元测试过程。 文章目录1 单元测试1.1 场景举例1.2 简单的测试方法2 Test Harness建立2.1 模型配置2.2 创建Test Harness3 总结1 单元测试 单元测试&#xff0c;简单来说就是在Simulink模型中只测试一小…