leetcode LRU 缓存
leetcode: LRU 缓存
LRU 全称为 Least Recently Used,最近最少使用,常常用于缓存机制,比如 cpu 的 cache 缓存,使用了 LRU 算法。LRU 用于缓存机制时,关键的是当缓存满的时候有新数据需要加载到缓存的,这个时候需要淘汰谁的问题。
如下图所示,表示 LRU 算法的过程。假如有一个缓存,共有 4 个存储空间,按访问时间进行排序,最左边的存储空间存储的是最近访问的数据,最右边的存储空间存储的是最长时间没有访问的数据。
(1)一开始,缓存是空的,这个时候向缓存中放入一个数据 100,100 放到最左边的存储空间
(2)向缓存中放入一个数据 50,此时缓存有空余空间,所以将已有的数据向后移动,将 50 放到缓存的最左边
(3)向缓存中放入数据 500, 步骤与上一步相同
(4)向缓存中放入数据 1000,步骤与上一步相同
(5)读取数据 100,读取之后 100 就是最后访问的数据了,所以将 100 移到缓存的最左边,其它数据依次向后移动
(6)向缓存中放入数据 1,此时缓存是满的,所以需要先淘汰一个数据,从访问时间来看,最后一次访问 50 的间隔时间最长,也就是排在最右边的数据,所以将 50 淘汰,其它数据向后移动,将新数据 1 放入最左边的位置

如下是题目描述,题目的最后要求 get() 和 put() 的时间复杂度都要是 O(1) 的。使用数组来表示缓存难以满足 O(1) 的要求,因为在 put 或者 get 的时候,会引起数组数据的移动,数组中数据的移动时间复杂度是 O(n) 的。所以需要使用链表来表示缓存,当访问一个数据的时候需要将当前这个数据从原来的位置上删除,然后加到链表的头部,删除一个节点的话,需要将这个节点的前一个节点和下一个节点连接起来,如果使用单向链表的话,那么只能找到这个节点的下一个节点,找不到上一个节点,所以需要使用双向链表。


(1)使用双向循环链表来表示缓存
(2)为了满足时间复杂度是 O(1) 的要求,使用 data_addr_ 数组来保存节点的地址,数组的下标是 key,题目中说明了 key 的取值范围是 [0, 10000],所以可以使用一个数组来表示。使用 map 也不能保证时间复杂度是 O(1) 的,map 一般使用红黑树来实现,时间复杂度是 O(logn) 的。把数组的下标当 key,数组元素的值就是值,数组本省也可以当做一个简单的 map 来使用。
(3)当 put 数据时,要进行判断现在缓存是不是满了,如果满的话需要删除最久没有访问的数据,head_->next 保存最新访问的数据,head_->prev 保存最久没有访问的数据
struct Node {int key;int value;struct Node *next;struct Node *prev;
};class LRUCache {
public:LRUCache(int capacity) {capacity_ = capacity;head_ = new Node();head_->next = head_;head_->prev = head_;}int get(int key) {Node *node = data_addr_[key];if (node == nullptr) {return -1;}ListUnLink(node);ListLinkHead(node);return node->value;}void put(int key, int value) {if (data_addr_[key] != nullptr) { Node *node = data_addr_[key];ListUnLink(node);node->value = value;ListLinkHead(node);} else {Node *new_node = new Node();new_node->key = key;new_node->value = value;new_node->next = nullptr;new_node->prev = nullptr;if (count_ == capacity_) {Node *to_delete = head_->prev;ListUnLink(to_delete);data_addr_[to_delete->key] = nullptr;delete to_delete;count_--;}ListLinkHead(new_node);data_addr_[key] = new_node;count_++;}}void ListLinkHead(struct Node *ele) {ele->next = head_->next;ele->next->prev = ele;head_->next = ele;ele->prev = head_;}void ListUnLink(struct Node *ele) {ele->prev->next = ele->next;ele->next->prev = ele->prev;}private:int capacity_ = 0;int count_ = 0;Node *data_addr_[10001] = {nullptr};struct Node *head_ = nullptr;};相关文章:
leetcode LRU 缓存
leetcode: LRU 缓存 LRU 全称为 Least Recently Used,最近最少使用,常常用于缓存机制,比如 cpu 的 cache 缓存,使用了 LRU 算法。LRU 用于缓存机制时,关键的是当缓存满的时候有新数据需要加载到缓存的,这个…...
LeetCode 2786.访问数组中的位置使分数最大:奇偶分开记录(逻辑还算清晰的题解)
【LetMeFly】2786.访问数组中的位置使分数最大:奇偶分开记录(逻辑还算清晰的题解) 力扣题目链接:https://leetcode.cn/problems/visit-array-positions-to-maximize-score/ 给你一个下标从 0 开始的整数数组 nums 和一个正整数 …...
嵌入式仪器模块:音频综测仪和自动化测试软件
• 24 位分辨率 • 192 KHz 采样率 • 支持多种模拟/数字音频信号的输入/输出 应用场景 • 音频信号分析:幅值、频率、占空比、THD、THDN 等指标 • 模拟音频测试:耳机、麦克风、扬声器测试,串扰测试 • 数字音频测试:平板电…...
计算商场折扣 、 判断体重指数 题目
题目 JAVA5 计算商场折扣分析:代码: JAVA6 判断体重指数分析:代码:大佬代码: JAVA5 计算商场折扣 描述 牛牛商场促销活动: 满100全额打9折; 满500全额打8折; 满2000全额打7折&…...
input输入框禁止输入小数点方法
使用blur事件: <el-input v-model"number" type"number" placeholder"请输入" blur"numberBlur" /> 第一种: 使用parseInt转为整数: this.number parseInt(this.number);第二种ÿ…...
使用adb通过wifi连接手机
1,手机打开开发者模式,打开无线调试 2,命令行使用adb命令配对: adb pair 192.168.0.102:40731 输入验证码:422859 3,连接设备: adb connect 192.168.0.102:36995 4,查看连接状态:…...
如何一键拷贝PPT中的所有文字?
有时我们可能需要引用PPT的文字,但一个幻灯片一个幻灯片拷贝很是麻烦,我们想一键拷贝PPT中所有幻灯片中的内容(最近我就遇到了这个需求)。今天就来讲讲这个一键拷贝的技巧。因为大家可能会遇到同样的问题,所以在此记录…...
Hive的存储格式和压缩算法的特点和选择
1、数据存储格式: ①TEXTFILE HIVE 中默认的存储格式; 一般使用在数据贴源层(ODS 或 STG) ,针对需要使用脚本 LOAD 加载数据到 HIVE 数仓表中的情况;需要把表里数据导出或直接可以查看等场景,作为BI供数 易读性…...
C语言中的枚举类型(enum)是如何定义的
在C语言中,枚举类型(enum)是一种用户定义的数据类型,它允许为整数值指定一个易读的名字。枚举类型通常用于表示固定数量的可能值,例如一周的七天或颜色的集合。 枚举类型的定义使用关键字 enum,后面跟着枚…...
SPI通信协议
一、SPI通信 1、SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线 2、四根通信线:SCK(Serial Clock)、MOSI(Master Output Slave Input)、MISO(Master In…...
【免费Web系列】大家好 ,今天是Web课程的第二一天点赞收藏关注,持续更新作品 !
这是Web第一天的课程大家可以传送过去学习 http://t.csdnimg.cn/K547r 员工管理 1. 条件分页查询 1.1 概述 在页面原型中,我们可以看到在查询员工信息列表时,既需要根据条件动态查询,还需要对查询的结果进行分页处理。 那要完成这个页面…...
【单片机毕业设计选题24007】-基于STM32和阿里云的家庭健康数据监测系统
系统功能: 本课题设计是基于STM32单片机作为控制主体,通过HX711称重模块,HC-SR04超声波测距模块,红外测温,心率传感器等模块通过I2C或SPI接口与STM32进行通信,并读取传感器输出的身高,体重,心率…...
基于微信公众号开发h5的前端流程
1.首先公众号进行配置,必须要https域名 还有个txt文件,有弹框提示需要下载放在服务器上 前端处理code的代码封装 // 微信公众号授权 export function wxAuthorize(calback) {// 非静默授权,第一次有弹框 这里的回调页面就是放在服务器上微信…...
python操作数据库,django操作数据库
安装驱动 pip install mysqlclient工程同名app下的settings.py DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: test,USER: root,PASSWORD: hirain123,HOST: localhost,PORT: 3306,OPTION; {init_command: SET sql_model"STRICT_TRANS_TABLES",}} …...
React框架资源
React框架资源可以从多个方面获取,包括官方文档、教程、书籍、社区等。以下是一些React框架资源的清晰分点和归纳: 官方文档 新官方文档:React在2023年3月发布了全新的官方文档,位于https://react.dev/。新文档包含教程、指南…...
【数据结构】初识数据结构之复杂度与链表
【数据结构】初识数据结构之复杂度与链表 🔥个人主页:大白的编程日记 🔥专栏:C语言学习之路 文章目录 【数据结构】初识数据结构之复杂度与链表前言一.数据结构和算法1.1数据结构1.2算法1.3数据结构和算法的重要性 二.时间与空间…...
word怎么单页横向设置(页码不连续版)
打开word,将光标放在第一页的最后位置。 然后点击布局下的分隔符,选择下一页。 将光标放在第二页的开头,点击布局下的纸张方向,选择横向即可。 效果展示。 PS:如果那一页夹在两页中间,那么在…...
搭建 Tomcat 集群【Nginx 负载均衡】
当我们想要提高后端服务器的并发性能,可以通过分配更多的资源给 Tomcat 服务器,但是这只能提高一部分的性能。因为每台 Tomcat 的服务器是有最大连接数为 200.所以即可拥有无穷无尽的内存,也会因为单台 Tomcat 的原因而无法发挥这些资源的最大…...
深入理解指针(二)
目录 1. 数组名的理解 2. 使用指针访问数组 3. ⼀维数组传参的本质 4. 冒泡排序 5. 二级指针 6. 指针数组 7. 指针数组模拟二维数组 1. 数组名的理解 有下面一段代码: #include <stdio.h> int main() {int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int* p &arr[…...
【Qt 学习笔记】Qt窗口 | 标准对话框 | 文件对话框QFileDialog
博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Qt窗口 | 标准对话框 | 文件对话框QFileDialog 文章编号:Q…...
STM32CubeIDE工程复制粘贴保姆级教程:告别重复配置,5分钟搞定新项目
STM32CubeIDE工程复制粘贴保姆级教程:告别重复配置,5分钟搞定新项目 每次启动新项目时,你是否还在重复那些繁琐的初始化步骤?从零开始配置时钟树、外设参数、中断优先级,不仅耗时费力,还容易出错。对于经验…...
Qt桌面应用集成PaddleOCR:从环境搭建到精准识别的实践指南
1. 环境准备:搭建PaddleOCR的Qt开发环境 第一次在Qt里折腾PaddleOCR时,我对着官方文档折腾了半天还是报错,后来发现是第三方库的路径没配好。这里分享下我踩坑后总结的可靠方案。 核心依赖三件套:PaddlePaddle推理库、PaddleOCR C…...
使用ZLMRTCClient.j实现webRtc流播放
1. 核心播放器组件封装 (WebRTCPlayer.vue)为了在项目中复用播放逻辑,我们首先封装一个 WebRTCPlayer 组件。该组件主要负责:初始化播放器实例:配置 ZLMRTCClient.Endpoint。处理自动播放:解决浏览器禁止带音频自动播放的问题。生…...
MDXEditor指令系统详解:如何扩展Markdown语法
MDXEditor指令系统详解:如何扩展Markdown语法 【免费下载链接】editor A rich text editor React component for markdown 项目地址: https://gitcode.com/gh_mirrors/editor/editor MDXEditor是一个功能丰富的React组件,专为Markdown编辑设计&am…...
别再手动整理了!用Python脚本5分钟搞定ImageNet验证集标签映射(附完整代码)
5分钟极速搞定ImageNet验证集标签映射:Python自动化实战指南 每次处理ImageNet验证集时,你是否也对着那些晦涩的数字标签头疼不已?手动查表不仅效率低下,还容易出错。今天我们就来彻底解决这个痛点——用Python脚本自动完成标签映…...
告别模糊边界!用Monodepth2实战KITTI深度估计,详解自动掩码与最小重投影损失
告别模糊边界!用Monodepth2实战KITTI深度估计,详解自动掩码与最小重投影损失 深度估计是计算机视觉领域的一项基础任务,它试图从2D图像中恢复出3D场景的几何信息。在自动驾驶、机器人导航、增强现实等应用中,准确的深度感知至关重…...
眼图分析:高速数字信号完整性的关键工具
1. 眼图基础概念解析 眼图(Eye Diagram)是数字信号完整性分析中最重要的工具之一。作为一名硬件工程师,我每天都会用眼图来评估信号质量。简单来说,眼图就是将数字信号在时间轴上重复叠加后形成的图形,因其形状类似人眼…...
万象视界灵坛基础教程:PyTorch+Transformers环境搭建与CLIP零样本推理入门
万象视界灵坛基础教程:PyTorchTransformers环境搭建与CLIP零样本推理入门 1. 环境准备与快速部署 1.1 系统要求 Python 3.8或更高版本支持CUDA的NVIDIA GPU(推荐)至少8GB显存(CLIP-ViT-L/14模型需求)10GB以上可用磁…...
Vue3+Three.js实战:拆解Xtreme1点云标注工具的技术架构
Vue3Three.js深度实战:构建工业级3D点云标注工具的技术解析 在自动驾驶、工业检测和机器人视觉领域,3D点云标注工具正成为AI训练数据生产的核心基础设施。Xtreme1作为开源多模态标注平台的代表,其pc-tool模块采用Vue3Three.js技术栈实现了专…...
别再手动数了!用Apache POI和iText,5行代码搞定Java批量统计文档页数
5行代码实现Java批量文档页数统计:Apache POI与iText的高效实践 当你在整理年度报告、审计文档或准备印刷材料时,是否曾被成百上千份文档的页数统计折磨得焦头烂额?手动打开每个文件查看页数不仅效率低下,还容易出错。今天&#x…...
