面试题常考: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) 的平均时间复杂度运行。
示例:
输入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4
思路:
1.题目中存放的数据是键值对形式的,所以我们可以采用哈希表(unordered_map)来实现
2.同时,题目要求get()、put()的时间复杂度为O(1),也就是能够快速插入、删除元素,来确保时间复杂度低,最佳的数据结构应该是链表,这里用双向链表最高效
所以,我们需要添加一个双向链表的结构体和无序map来对数据实现LRU缓存。
详细过程参考下面代码:
Code:
class LRUCache {
public://双链表的结构体struct Node{int key;int val;//前驱和后继指针Node * prev,*next;//构造函数Node():key(0),val(0),prev(nullptr),next(nullptr){}Node(int m_key,int m_val):key(m_key),val(m_val),prev(nullptr),next(nullptr){}};unordered_map<int,Node*> map;//哈希表,用来存储键值对Node* head;//头节点Node* tail;//尾节点int m_capacity;//总容量int size;//哈希表当前容量LRUCache(int capacity):m_capacity(capacity),size(0) {//初始化头尾节点head=new Node();tail=new Node();//构建双向链表head->next=tail;tail->prev=head;}//获取函数int get(int key) {//如果哈希表中不存在键为key,直接返回-1if(!map.count(key)){return -1;}//存在key//获取链表的节点Node* node=map[key];remove(node);//删除节点AddNodeToHead(node);//将当前节点移至头节点之后return node->val;//返回节点的值}void put(int key, int value) {//如果当前key值已存在if(map.count(key)){//获取节点Node* node=map[key];//改变节点的值为新的valuenode->val=value;remove(node);//删除节点AddNodeToHead(node);//将节点移至头节点之后}//不存在,则加入到哈希表中else{//判断容量是否已满if(size==m_capacity)//满了{//获取最近最久未使用的节点,也就是尾节点的前驱节点Node* removed=tail->prev;//从哈希表中移除该节点map.erase(removed->key);//删除节点remove(removed);//当前容量--size--;}//创建新节点Node* node=new Node(key,value);AddNodeToHead(node);//将节点移至头节点之后map[key]=node;//加入哈希表中size++;//当前容量++}}//删除节点函数void remove(Node* node){node->prev->next=node->next;node->next->prev=node->prev;}//将节点移至头节点之后void AddNodeToHead(Node* node){node->prev=head;node->next=head->next;head->next->prev=node;head->next=node;}
};相关文章:
面试题常考:LRU缓存
题目: 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值&…...
Redis 教程 - 持久化
Redis 教程 - 持久化 在 Redis 中,持久化是指将数据从内存保存到磁盘上,以便在重启或服务器故障后仍能恢复数据。Redis 提供了两种持久化方式:RDB(Redis Database)和 AOF(Append-Only File)。本…...
2023 大学生数学建模竞赛-C题-第一问
题目: 在生鲜商超中,一般蔬菜类商品的保鲜期都比较短,且品相随销售时间的增加而变差, 大部分品种如当日未售出,隔日就无法再售。因此,商超通常会根据各商品的历史销售和需 求情况每天进行补货。 由于商超销…...
设计模式3 观察者模式
一 观察者模式 1.1 概述 观察者模式是一种行为模式,又称之为“发布/订阅”模式,在该模式中被观察的对象叫主题,依赖主题的对象被称为观察者,当主题发生改变时,会通知所有观察者进行更新。多个对象存在一对多的关系&a…...
如何防止网络安全攻击
为了防止网络安全攻击,以下是一些常见的防御措施和建议: 使用强密码:确保使用足够长、复杂且随机的密码,并定期更改密码。不要在多个账户中重复使用相同的密码。 更新和修补软件:定期更新操作系统、应用程序和安全补丁…...
怎么从0到1实现一个PHP框架?
写在前面 本人开发的框架在2021年年初开发完成,后面没有再做过任何维护和修改。是仅供大家参考交流的学习项目,请勿使用在生产环境,也勿用作商业用途。 框架地址: https://github.com/yijiebaiyi/fast_framework 整体思路 开发…...
脚本:python实现樱花树
文章目录 代码效果 代码 from turtle import * from random import * from math import * def tree(n, l):pd () # 下笔# 阴影效果t cos ( radians ( heading () 45 ) ) / 8 0.25pencolor ( t, t, t )pensize ( n / 3 )forward ( l ) # 画树枝if n > 0:b random () *…...
公司内部传文件怎么安全——「用绿盾透明加密软件」
为保证公司内部文件传递的安全性,可以使用天锐绿盾透明加密软件来进行保护。以下是具体的操作步骤: 在公司内部部署天锐绿盾加密软件,确保需要传递的文件都能受到加密保护。 在员工的工作电脑上安装天锐绿盾客户端,并设置好相关的…...
提高使用VS Code工作效率的技巧
提高使用VS Code工作效率的技巧 时间轴视图:本地源代码控制 时间轴视图为我们提供了内置的源代码控制。 我们中的许多人都知道 Git 和其他源代码控制工具有多么有用,它们可以帮助我们轻松跟踪文件更改并在需要时恢复到之前的状态。 因此,…...
软件系统兼容性测试都要注意哪些问题?
兼容性 软件兼容性测试具有相同的含义,它是任何第三方 Web 应用程序测试服务不可分割的一部分。在众多不同的设置中,最重要的是完全的客户满意度,并且可以通过全面的兼容性测试来达到最佳效果。众所周知,软件质量保证是克服 IT 挑…...
索尼 toio™应用创意开发征文|toio俄罗斯方块游戏
目录 引言 摘要 创意简述 准备工作|手工开始 代码编写|合理集成 使用体验|近乎奇妙 引言 索尼toio™编程机器人是一款引领技术创新的产品,为开发者提供了一个全新的编程和创造平台。toio™的设计旨在将技术、塑性和乐趣融为…...
C#事件event
事件模型的5个组成部分 事件拥有者(event source)(类对象)(有些书将其称为事件发布者) 事件成员(event)(事件拥有者的成员)(事件成员就是事件本身…...
气传导耳机什么牌子好?盘点五款好用的气传导耳机分享
对于气传导耳机,大家最关心的可能是佩戴会不会不舒服?音质好不好?会不会漏音?等问题。面对这些问题,今天我就为大家推荐几款市面上最好的气传导耳机,总有一款适合你的! ①NANK南卡00压气传导…...
业绩走低,毛利率下滑,海外市场能否成为极米科技救命稻草?
撰稿|行星 来源|贝多财经 8月30日,成都极米科技股份有限公司(SH:688696,下称“极米科技”)发布2023年半年度业绩报告。财报显示,极米科技2023年上半年的业绩出现了大幅下滑,其中收入同比减少两成…...
轻松敏捷开发流程之Scrum
Scrum是一种敏捷开发流程,它旨在使软件开发更加高效和灵活。Scrum将软件开发过程分为多个短期、可重复的阶段,称为“Sprint”。每个Sprint通常为两周,旨在完成一部分开发任务。 在Scrum中,有一个明确的角色分工: 产品…...
Vue3+Element Plus实现el-table跨行显示(非脚手架)
Vue3Element Plus实现el-table跨行显示 app组件内容使用:span-method"objectSpanMethod"自定义方法实现跨行显示查询方法初始化挂载新建一个html即可进行测试,完整代码如下效果图 app组件内容 <div id"app"><!-- 远程搜索 --><e…...
生成订单30分钟未支付,则自动取消,该怎么实现?
今天给大家上一盘硬菜,并且是支付中非常重要的一个技术解决方案,有这块业务的同学注意自己试一把了哈! 在开发中,往往会遇到一些关于延时任务的需求。例如 生成订单30分钟未支付,则自动取消 生成订单60秒后,给用户…...
WebGIS外包开发流程
WebGIS开发流程需要综合考虑前端和后端开发、地理信息数据处理、用户需求和安全性等多个方面。成功的WebGIS应用程序需要不断地进行更新和维护,以适应变化的需求和技术。WebGIS开发是一个复杂的过程,通常包括以下主要步骤。北京木奇移动技术有限公司&…...
pytorch学习——LSTM和GRU
参考书籍:https://zh-v2.d2l.ai/chapter_recurrent-modern/lstm.html 参考论文: https://colah.github.io/posts/2015-08-Understanding-LSTMs/ 简介: LSTM(长短期记忆网络)和GRU(门控循环单元)…...
【Python】Python 利用模块实现单例模式
Python 利用模块实现单例模式 在GOF的23种设计模式中,单例是最常使用的模式,通过单例模式可以保证系统中 一个类只有一个实例而且该实例易于被外界访问,从而方便对实例个数的控制并节约系统资 源。每当大家想要实现一个名为XxxMangcr的类时&…...
GME多模态向量模型实战部署:华为云ModelArts一键启动图文检索
GME多模态向量模型实战部署:华为云ModelArts一键启动图文检索 1. 引言:多模态检索的实用价值 想象一下,你正在管理一个大型数字资产库,里面有成千上万的图片和文档。当你想找"去年会议上讨论过的那张数据流程图"时&am…...
基于Phi-4-mini-reasoning的智能运维异常检测系统
基于Phi-4-mini-reasoning的智能运维异常检测系统 1. 运维监控的痛点与智能化需求 运维团队每天都要面对海量的日志数据、监控指标和系统告警。传统监控系统往往只能做到简单的阈值告警,当系统出现异常时,运维人员需要手动翻阅成千上万条日志ÿ…...
2026 Global Ion Exchange Resin Systems Market Trends:关税扰动下的工程水处理系统重构与产业链迁移逻辑
观点 离子交换树脂系统的竞争核心,已经不再是“树脂材料”,而是“系统工程能力 供应链组织能力”。 2026年关税变量的加入,本质上正在把这个行业从“化工材料赛道”,推向“工程系统全球制造网络”的复合竞争阶段。一、这不是树脂…...
千问3.5-2B在办公提效场景:会议白板照片文字提取+要点总结实战
千问3.5-2B在办公提效场景:会议白板照片文字提取要点总结实战 1. 办公场景的痛点与解决方案 1.1 会议记录的传统困境 每次开完会,最让人头疼的就是整理会议记录了。特别是那些在白板上写满讨论要点的会议,你需要: 对着白板照片…...
PXE装机避坑大全:从TFTP根目录设置到Kickstart无人值守的13个常见错误修复
PXE装机避坑大全:从TFTP根目录设置到Kickstart无人值守的13个常见错误修复 在企业级IT运维中,PXE(预启动执行环境)网络装机技术因其高效、自动化的特点,已成为服务器批量部署的标配方案。但看似简单的PXE部署流程背后&…...
Cursor Composer 2 技术报告拆解:MoE 预训练、RL 环境设计与 CursorBench 基准的工程实践
在生产级代码仓库里,一个 AI Agent 面对的往往不是“实现某个功能”这样清晰的任务,而是“新特性上线后出现诡异 bug,日志里只有 954 个 JSON 响应,栈踪迹完全不可靠”。它必须自己跨文件定位、写启发式检测器、调参避免误报&…...
革新性PDF可视化标记技术:从原理到实践的全方位解析
革新性PDF可视化标记技术:从原理到实践的全方位解析 【免费下载链接】obsidian-pdf-plus PDF: the most Obsidian-native PDF annotation & viewing tool ever. Comes with optional Vim keybindings. 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-…...
STM32CubeIDE用DAP下载器?这份OpenOCD配置文件修改与复位难题解决指南请收好
STM32CubeIDE深度调优:DAP下载器OpenOCD配置与自动复位难题实战解析 当你在STM32CubeIDE中切换ST-LINK与DAP调试器时,是否注意到两者在用户体验上的显著差异?特别是当使用DAP调试器时,每次下载后都需要手动复位开发板才能运行程序…...
CH347的JTAG模式怎么选?实测F/T型号在openFPGALoader下的速度与兼容性差异
CH347F与CH347T JTAG模式深度评测:openFPGALoader下的实战性能差异 当你在淘宝搜索"CH347模块"时,会发现两种主要型号:F型多功能版和T型切换版。价格相差无几,但商家描述往往含糊其辞。作为FPGA开发者,最关…...
Rust DLL注入技术深度解析:Rust-for-Malware-Development完整实现指南
Rust DLL注入技术深度解析:Rust-for-Malware-Development完整实现指南 【免费下载链接】Rust-for-Malware-Development Rust for malware Development is a repository for advanced Red Team techniques and offensive malwares & Ransomwares, focused on Rus…...
