面试题常考: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的类时&…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...