leetcode热题HOT146. LRU 缓存

一、问题描述:

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

二、解题思路:

  1. 使用哈希表和双向链表来实现。哈希表用于快速查找键对应的节点,通过缓存数据的键映射到其在双向链表中的位置;双向链表用于维护键值对的顺序,靠近头部的键值对是最近使用的,而靠近尾部的键值对是最久未使用的。
  2. 具体步骤如下:
    ①定义一个节点类 Node,包含 key、value、prev 和 next 四个属性,分别表示键、值、前驱节点和后继节点。
    ②定义 LRUCache 类,包含哈希表 cache、双向链表 dll、缓存容量 capacity、当前缓存大小 size 四个成员变量。
    ③LRUCache 构造函数中初始化哈希表和双向链表,并设置缓存容量。
    ④实现 get 方法:如果 key 存在于哈希表中,则将对应节点移到双向链表头部,并返回对应的值。如果 key 不存在,则返回 -1。
    ⑤实现 put 方法:
    (1)如果 key 存在于哈希表中,则更新对应节点的值,并将节点移到双向链表头部。
    (2)如果 key 不存在于哈希表中:如果缓存已满,需要先移除双向链表尾部的节点,并从哈希表中删除对应的键。然后创建一个新节点,并将其添加到双向链表头部,并将对应的键值对存入哈希表中。

三、代码示例:

public class LRUCache {class DLinkedNode {int key;int value;DLinkedNode prev;DLinkedNode next;// 双向链表节点构造函数public DLinkedNode() {}// 双向链表节点构造函数public DLinkedNode(int _key, int _value) {key = _key;value = _value;}}// 使用哈希表实现快速查找private Map<Integer, DLinkedNode> cache = new HashMap<>();private int size;private int capacity;private DLinkedNode head, tail;// 初始化LRU缓存public LRUCache(int capacity) {this.size = 0;this.capacity = capacity;     // 使用伪头部和伪尾部节点head = new DLinkedNode();tail = new DLinkedNode();head.next = tail;tail.prev = head;}// 获取缓存中的值public int get(int key) {DLinkedNode node = cache.get(key);if (node == null) {return -1; // 如果 key 不存在,返回 -1}// 如果 key 存在,先通过哈希表定位,再移到头部moveToHead(node);return node.value;}// 向缓存中添加键值对public void put(int key, int value) {DLinkedNode node = cache.get(key);if (node == null) {// 如果 key 不存在,创建一个新的节点DLinkedNode newNode = new DLinkedNode(key, value);// 添加进哈希表cache.put(key, newNode);// 添加至双向链表的头部addToHead(newNode);++size;if (size > capacity) {// 如果超出容量,删除双向链表的尾部节点DLinkedNode tail = removeTail();// 删除哈希表中对应的项cache.remove(tail.key);--size;}} else {// 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部node.value = value;moveToHead(node);}}// 将节点添加至双向链表头部private void addToHead(DLinkedNode node) {node.prev = head;node.next = head.next;head.next.prev = node;head.next = node;}// 从双向链表中移除节点private void removeNode(DLinkedNode node) {node.prev.next = node.next;node.next.prev = node.prev;}// 将节点移到双向链表头部private void moveToHead(DLinkedNode node) {removeNode(node);addToHead(node);}// 移除双向链表尾部节点private DLinkedNode removeTail() {DLinkedNode res = tail.prev;removeNode(res);return res;}
}
  • 时间复杂度分析:
    ①构造函数 LRUCache(int capacity)时间复杂度:O(1)
    创建哈希表、头部和尾部节点,初始化变量,时间复杂度都是常数级别的操作。
    ②get(int key) 方法时间复杂度:O(1)
    通过哈希表进行查询,如果找到了对应的节点,则将其移到双向链表头部。哈希表的查询操作和双向链表的移动操作都是常数级别的。
    ③put(int key, int value) 方法时间复杂度:O(1)
    如果节点不存在,则创建新节点并加入到头部,同时更新哈希表。如果缓存已满,则删除尾部节点。所有操作都是常数级别的。

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

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

相关文章

220V转3.3V线性降压芯片WT5100

220V转3.3V线性降压芯片WT5100 WT5100就是那个离线式的稳压器芯片&#xff0c;没有电感的那种。里面内置了650V的大功率MOSFET&#xff0c;启动控制电路&#xff0c;电压控制电路&#xff0c;交流信号检测电路等等。通过切换SEL管脚&#xff0c;它就能输出5V或3.3V的电压。不需…

一本免费开源的电子书籍!这个 71.8k star 的项目,让你轻轻松松学会算法【文末有福利】

话说作为一名程序员&#xff0c;肯定都少不了在准备面试的时候刷 LeetCode 的算法题吧。虽然面试考察的算法题在工作中用到的非常少&#xff0c;但是确实是能让我们对常用的数据结构有更深刻的理解&#xff0c;以及对思维逻辑有很大的提升。不过枯燥的刷题可能让新手无从下手&a…

【Linux网络编程】UDP协议

UDP协议 1.再谈端口号端口号划分认识知名端口号(Well-Know Port Number)两个问题netstatpidof 2.UDP协议2.1UDP的特点2.2面向数据报2.3UDP的缓冲区2.4UDP使用注意事项2.5基于UDP的应用层协议 喜欢的点赞&#xff0c;收藏&#xff0c;关注一下把&#xff01; 1.再谈端口号 端口…

【Unity优化(二)】渲染优化

https://www.cnblogs.com/alan777/p/6204759.html CPU受限 开启Player Settings中的Graphics jobs。 在Player settings中的Graphics jobs选项决定了Unity是否使用工人线程去执行一些原本需要在主线程或者渲染线程中执行的任务&#xff0c;在支持这个功能的平台上&#xff0…

mysql匹配

文章目录 匹配和正则表达式匹配&#xff1a;like正则表达式&#xff1a;rlike&#xff08;与regexp完全一样没有区别&#xff09; 匹配和正则表达式 匹配&#xff1a;like %&#xff1a;用来匹配 0 个或多个字符 _&#xff1a;用来匹配1个字符 SELECT * FROM Websites WHER…

计算方法实验5:对鸢尾花数据集进行主成分分析(PCA)并可视化

任务 iris数据集包含150条数据&#xff0c;从iris.txt读取&#xff0c;每条数据有4个属性值和一个标签&#xff08;标签取值为0&#xff0c;1&#xff0c;2&#xff09;。要求对这150个4维数据进行PCA&#xff0c;可视化展示这些数据在前两个主方向上的分布&#xff0c;其中不…

笔记84:关于递归法的一些感悟

题目1&#xff1a;二叉树的前序遍历 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(…

京东详情比价接口优惠券(2)

京东详情API接口在电子商务中的应用与作用性体现在多个方面&#xff0c;对于电商平台、商家以及用户都带来了显著的价值。 首先&#xff0c;从应用的角度来看&#xff0c;京东详情API接口为开发者提供了一整套丰富的功能和工具&#xff0c;使他们能够轻松地与京东平台进行交互。…

后台运行程序时报错

问题描述&#xff1a;使用pycharm连接服务器运行程序时&#xff0c;可以正常运行。但是使用Termius终端运行时报错&#xff08;运行时切换到和pycharm相同的路径&#xff09;。 2024-04-15 14:35:01.663900: I external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:454] …

jeecg 3.4.3前后端分离获取,前端获取当前登录人信息

1. store —>modules—>user.js下 可以查看有哪些信息 2. 使用方式 2.1 //获取登录用户的信息 import user from ‘/store/modules/user’ 2.2 export下 export default { user } 2.3 可以在created中直接打印信息 const useruser.state; console.log(“当前登录人:”…

USB设备热插拔流程解析

设备热插拔 i2c,spi都是主机驱动初始化的时候&#xff0c;就会根据设备树来添加设备 pci的话&#xff0c;主机初始化的时候&#xff0c;会通过总线去遍历枚举card设备 sdio的话&#xff0c;主机驱动初始化的时候&#xff0c;会去枚举卡&#xff1b;插卡可能会触发主机中断&a…

物业满意度调查如何开展?

物业管理行业的服务水平对于提升居民生活质量、维护社区安全和保障房产价值起着重要作用&#xff0c;近年来受地产关联方房屋交付影响&#xff0c;以及疫情后物业投入减少&#xff0c;物业企业对社区环境、设施和公共区域的维护减弱&#xff0c;2023年的降幅尤其明显&#xff0…

Java基础(变量)

什么是变量&#xff1f; 变量&#xff1a;在程序的执行过程中&#xff0c;其值有可能发生改变的量&#xff08;数据&#xff09; 变量的使用场景 当某个数据经常发生改变时&#xff0c;我们也可以用变量储存。当数据变化时&#xff0c;只要修改变量里面记录的值即可。 变量…

加州大学戴维斯分校最新Nature Ecology Evolution(IF=19)!入侵植物在成为生态威胁之前可能会休眠几十年甚至几百年

根据加利福尼亚大学戴维斯分校领导的一项新研究&#xff0c;入侵植物在被引入环境后可能会休眠几十年甚至几百年&#xff0c;然后才会迅速扩展并造成生态破坏&#xff08;非常意外和可怕&#xff09;。这项发表在《Nature Ecology & Evolution》上的研究调查了全球九个地区…

掌握JMeter HTTP 请求头:简单易懂

在深入研究 JMeter 的过程中&#xff0c;任何涉及性能测试或接口验证的专业人员都会认识到&#xff0c;合理配置HTTP请求头部信息是实现精确测试的关键步骤之一。不同情景下&#xff0c;如数据提交形式的不同&#xff08;例如 JSON、XML 等&#xff09;&#xff0c;或是需要通过…

【react】零基础教学写一个最简单的网站和装饰思路

你想要把你的数据放在网络上&#xff0c;给别人分享&#xff0c;难道就是直接闹脑中想一想就能做了么&#xff1f; 并不是&#xff0c;我们看到有五花八门的网站。 这些网站都是非常的好看&#xff0c;玲琅满目的商品让你想要去下单购买。 一个复杂的商城是很复杂&#xff0c; …

英语技术会议常用语

个人整理。 自我介绍&#xff1a; Hello everyone, Im [Your Name], and Im excited to be here today. I work as [Your Position] at [Your Company/Organization], where I focus on [Brief Description of Your Role or Expertise]. Im looking forward to our discussion…

YoloV8改进策略:Block改进|轻量级的Mamba打造优秀的YoloV8|即插即用,简单易懂|附Block结构图|检测、分割、关键点均适用(独家原创)

摘要 无Mamba不狂欢,今天给大家带来一个基于轻量级Mamba的改进。模块简单易懂,即插即用! 带领大家去征服更高的领域。 论文:《LightM-UNet:Mamba 辅助的轻量级 UNet 用于医学图像分割》 https://arxiv.org/pdf/2403.05246.pdf UNet及其变体在医学图像分割中得到了广泛…

uniapp开发 如何获取IP地址?

一、需求 使用uniapp开发小程序时&#xff0c;需要调取【记录日活动统计】的接口&#xff0c;而这个接口需要传递一个ip给后台&#xff0c; 那么前端如何获取ip呢&#xff1f;下面代码里可以实现 二、代码实现 1.在项目的manifest.json中配置一下网络权限&#xff1a; &quo…

Python离线语音识别高准确率方案分析及代码实现

背景: 随着信息技术的飞速发展和人工智能的广泛应用,语音识别技术已成为现代通信和人机交互领域的重要组成部分。离线语音识别技术,作为语音识别的一个分支,因其无需实时连接网络、保护用户隐私等特性,在特定场景中发挥着越来越重要的作用。 离线语音识别技术主要指的是…