LRU 缓存

题目链接

LRU 缓存

题目描述


注意点

  • 如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字
  • 函数 get 和 put 必须以 O(1) 的平均时间复杂度运行

解答思路

  • 如果想以O(1)的速度进行get,则需要将对应的key、value存到map中
  • 如果想以O(1)的速度进行put,又因为插入的时候可能由于空间已满需要将最久未使用的关键字,元素始终都在进行移动,所以需要使用链表来存储节点
  • 如果使用map存储key、value,链表中每个节点存储key、value,则在get某个节点需要将其移动到链表头部时查找该节点需要花费O(n)的时间,不满足题意,所以应该map存储的key为对应关键字的key,而存储的value应该是该key对应的链表节点

代码

class LRUCache {class DoublyLinkedList {int key;int value;DoublyLinkedList prev;DoublyLinkedList next;DoublyLinkedList() {}DoublyLinkedList(int key, int value) {this.key = key;this.value = value;}}int size;DoublyLinkedList head;DoublyLinkedList tail;Map<Integer, DoublyLinkedList> map;public LRUCache(int capacity) {size = capacity;map = new HashMap<>(capacity);head = new DoublyLinkedList();tail = new DoublyLinkedList();head.next = tail;tail.prev = head;}public int get(int key) {DoublyLinkedList node = map.get(key);if (node == null) {return -1;}// 将该节点移动到链表头部removeNode(node);moveToHead(node);return node.value;}public void put(int key, int value) {DoublyLinkedList node = new DoublyLinkedList(key, value);// key在链表中已存在,只更新了value值,则直接对map进行更新即可,还要将新节点移动到链表头部if (map.containsKey(key)) {DoublyLinkedList oldNode = map.get(key);removeNode(oldNode);map.put(key, node);moveToHead(node);return;}// key在链表中不存在,且链表还有多余空间,则只需要将新节点插到链表头部if (map.size() < size) {moveToHead(node);map.put(key, node);} else {// key在链表中不存在,且链表已满,则需要删除链表尾,同时将新节点插到链表头部map.remove(tail.prev.key);removeNode(tail.prev);moveToHead(node);map.put(key, node);}}public void moveToHead(DoublyLinkedList node) {DoublyLinkedList tmp = head.next;head.next = node;node.prev = head;node.next = tmp;tmp.prev = node;}public void removeNode(DoublyLinkedList node) {DoublyLinkedList prevNode = node.prev;DoublyLinkedList nextNode = node.next;prevNode.next = nextNode;nextNode.prev = prevNode;}
}

关键点

  • map中存储的value为key对应的链表中的节点
  • 如果能成功get到值,则需要将该节点移动到链表的头部,移动时,还要删除链表中老位置的该节点
  • 在put时,如果此时链表和map中已经有该关键字,只是更新其value值,则需要更新其在链表中的节点值,同时将该节点移动到链表同步;如果没有该关键字但是链表空间足够,则只需要建一个新节点插到链表头部即可;如果没有该关键字且链表空间已满,则需要将尾部节点删掉,再将新节点插入到头部
  • 在增加和删除链表节点时同时也要对map中的相应值进行更新

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

​ 基于单片机智能温室大棚控制系统

功能介绍 以51单片机作为主控系统&#xff1b; DS18B20温度采集模块检测温度&#xff1b; 光敏电阻和ADC0832组成的光照检测模块&#xff1b; 土壤湿度检测模块检测土壤湿度&#xff1b; CO2检测模块检测CO2浓度&#xff1b; LCD1602显示模块显示测量值、 若温度小于温度最…

ceph命令总结

ceph命令总结 一、集群 1、启动一个ceph 进程 2、查看机器的监控状态[查看集群健康状态细节] ceph health [detail]3、查看ceph的实时运行状态(常用) ceph -w4、检查信息状态信息(常用) ceph -s5、查看ceph存储空间 ceph df6、查看ceph集群中的认证用户及相关的key(常用…

【2023江西省研究生数学建模竞赛】第三题 植物的多样性 48页论文及Python代码

【2023江西省研究生数学建模竞赛】第三题 植物的多样性 48页论文及Python代码 相关链接 【江西省研究生数学建模竞赛】第一题 蒸汽发生器倒U型管内液体流动 70页论文及MATLAB代码 【江西省研究生数学建模竞赛】第一题 蒸汽发生器倒U型管内液体流动 70页论文及MATLAB代码 【2…

车道线检测|利用边缘检测的原理对车道线图片进行识别

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 这两个都是博主在学习Linux操作系统过程中的记录&#xff0c;希望对大家的学习有帮助&#xff01; 操作系统Operating Syshttps://blog.csdn.net/yu_cblog/category_12165502.html?spm1001.2014.3001.5482Linux S…

【深度学习】受限玻尔兹曼机 (RBM) 初学者指南

一、说明 受限玻尔兹曼机&#xff08;Restricted Boltzmann Machine&#xff0c;RBM&#xff09;是一种基于能量模型的人工神经网络。它只有一个隐层&#xff0c;将输入层和隐层中的每个神经元互相连接&#xff0c;但不同层的神经元之间没有连接。RBM是一种无向的概率图模型&am…

docker和k8s的学习介绍

docker: 出现是因为相比于虚拟机&#xff0c;资源复用更加灵活&#xff0c;虚拟机是一个完整的操作系统&#xff0c;占用空间大&#xff0c;启动慢&#xff1b;docker容器技术可以根据也无需求&#xff0c;配置不同的环境&#xff0c;不会互相影响。镜像操作方便迁移&#xff0…

一套完全开源,支持多租户,界面配置单点的后端框架JVS

JVS的多租户体系统 在IT系统中&#xff0c;“租户”&#xff08;tenant&#xff09;通常用于指代一种多租户架构&#xff08;multi-tenancy&#xff09;&#xff0c;它是一种软件架构模式&#xff0c;允许多个用户或组织共享相同的应用程序或系统实例&#xff0c;但彼此之间的…

7.5 SpringBoot 拦截器Interceptor实战 统一角色权限校验

文章目录 前言一、定义注解annotation二、拦截角色注解1. 在拦截器哪里拦截&#xff1f;2. 如何拦截角色注解&#xff1f;3. 角色如何读取?4. 最后做角色校验 三、应用&#xff1a;给管理员操作接口加注解四、PostMan测试最后 前言 在【7.1】管理员图书录入和修改API&#xf…

JMeter 中 3 种参数值的传递

目录 前言&#xff1a; (一) 从 CSV 文件读取要批量输入的变量 (二) 利用 Cookie 进行值的传递 (三) 利用正则匹配提取上一个接口的返回数据作为下个请求的输入 前言&#xff1a; 在JMeter中&#xff0c;参数值的传递是非常重要的&#xff0c;因为它允许你在测试过程中动态…

右键pdf文件没有打印

问题描述 右键点pdf文件&#xff0c;弹出的菜单找不到打印选项。网上找了很多办法&#xff0c;然并卵啊。还是得靠自己慢慢摸索。 原因分析 新安装的win11系统&#xff0c;pdf文件默认可以用windows自带的edge浏览器打开。但是edge浏览器没有能力提供右键打印功能。 解决办法…

详解LeafLet中如何展示GeoServer发布的图层组

目录 前言 一、关于图层组 1、使用图层图组的好处 2、创建图层组 二、在Leaflet中展示图层组 1、新建Html模板框架 2、绑定地图map和底图设置 3、绑定图层组 总结 前言 在之前的博文中&#xff0c;曾经重点介绍如何使用LeafLet叠加Geoserver wms图层到已有底图的方法 ,…

Python应用:什么是爬虫?

文章目录 什么是爬虫虫之初&#xff0c;性本善&#xff1f;出行社交电商搜索引擎政府部门总结 面向监狱编程爬虫的君子协议什么是君子协议君子协议是怎么产生的&#xff1f;君子协议是什么内容&#xff1f;如何查看一个网站的robots协议违反君子协议的案例 参考文献 2022年初的…

x86架构ubuntu22下运行SFC模拟器zsnet

0. 环境 ubuntu22 1. apt安装 sudo apt install zsnes 2. 运行 zsnet 参考&#xff1a;在Ubuntu上用zsnes玩SFC游戏&#xff0c;https://blog.csdn.net/gqwang2005/article/details/3877121

Linux学习之系统默认打开的文件描述符、重定向

系统默认打开的文件描述符 一个进程默认会打开标准输入、标准输出、错误输出三个文件描述符。可以在/proc/PID/fd里边可以看到打开文件的描述符&#xff0c;PID需要改成具体的pid&#xff0c;比如可以使用A终端输入vim proctest之后按下回车键。 打开一个vim编辑窗口。 再打…

Unity游戏源码分享-卡通填色游戏Drawing Coloring Extra Edition 1.09

Unity游戏源码分享-卡通填色游戏Drawing Coloring Extra Edition 1.09 非常适合小朋友玩的小游戏 功能很齐全完善 项目地址&#xff1a;https://download.csdn.net/download/Highning0007/88050261

使用MFC CAD 的一些使用方式记录【追加ing】

1. 项目调试&#xff1a;由于项目很大&#xff0c;因此&#xff0c;我们调试的时候&#xff0c;不应该编译整个软件而是应该只编译对应的 类去做处理 2. debug 设置断点方面&#xff1a; 以往我们的操作都是在.exe直接执行文件上进行操作&#xff0c;但是&#xff0c;现在&am…

人工智能-神经网络

目录 1 神经元 2 MP模型 3 激活函数 3.1 激活函数 3.2 激活函数作用 3.3 激活函数有多种 4、神经网络模型 5、神经网络应用 6、存在的问题及解决方案 6.1 存在问题 6.2 解决方案-反向传播 1 神经元 神经元是主要由树突、轴突、突出组成&#xff0c;树突是从上面接收很多…

flutter开发实战-实现webview与Javascript通信JSBridge

flutter开发实战-实现webview与H5中Javascript通信JSBridge 在开发中&#xff0c;使用到webview&#xff0c;flutter实现webview是使用原生的插件实现&#xff0c;常用的有webview_flutter与flutter_inappwebview 这里使用的是webview_flutter&#xff0c;在iOS上&#xff0c;…

如何定制自己的应用层协议?|面向字节流|字节流如何解决黏包问题?如何将字节流分成数据报?

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量干货博客汇总https://blog.csdn.net/yu_cblog/c…

Excel中的Ctrl+Shift:功能及其使用方法

通过本教程,你将了解的功能以及如何在Excel中以最佳方式使用Ctrl+Shift。 我们可以在 Excel 中使用许多快捷方式来简化工作。其中一些有趣的使用了键盘上的 Ctrl 和 Shift 按钮。如果我们能够掌握这些快捷方式,我们应该能够在 Excel 中更有效地完成工作。 想知道我们可以在…