35 LRU缓存

LRU缓存

    • 题解1 双map(差2个testcases)
    • 题解2 哈希表+双向链表(参考)
    • 题解3 STL:list+unordered_map

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

在这里插入图片描述
提示:

  • 1 <= capacity <= 3000
  • 0 <= key <= 10000
  • 0 <= value <= 105
  • 最多调用 2 ∗ 1 0 5 2 * 10^5 2105getput

题解1 双map(差2个testcases)

class LRUCache {int LRUcapacity;map<int, int> cacheMap;map<int, int> usecases;int time = 0; static bool cmp(const pair<int, int>& lhs, const pair<int, int>& rhs) {  return lhs.second < rhs.second;  }  public:LRUCache(int capacity) {LRUcapacity = capacity;}int get(int key) {if(cacheMap.count(key)){// 记录访问时刻(value越大代表最近使用)usecases[key] = time++;return cacheMap[key];}else return -1;}void put(int key, int value) {if(cacheMap.count(key)){cacheMap[key] = value;usecases[key] = time++;}else{// 没满足O(1)的时间复杂度if(cacheMap.size() + 1 > LRUcapacity){// 拿到最早访问的关键字 value最小vector<pair<int, int>> usecasesVector(usecases.begin(), usecases.end());sort(usecasesVector.begin(), usecasesVector.end(), cmp);int idx = usecasesVector[0].first;cacheMap.erase(cacheMap.find(idx));usecases.erase(usecases.find(idx));}cacheMap[key] = value;usecases[key] = time++;}}
};/*** Your LRUCache object will be instantiated and called as such:* LRUCache* obj = new LRUCache(capacity);* int param_1 = obj->get(key);* obj->put(key,value);*/

在这里插入图片描述

题解2 哈希表+双向链表(参考)

class LRUCache {int LRUcapacity;// 双向链表保证每次找最近使用的操作时间复杂度为O(1)struct Node{int key;int value;Node* prev;Node* next;Node(): key(0), value(0), prev(nullptr), next(nullptr){}Node(int key1, int value1): key(key1), value(value1), prev(nullptr), next(nullptr){}};map<int, Node*> cacheMap;Node* head, *tail;
public:LRUCache(int capacity) {LRUcapacity = capacity;head = new Node();tail = new Node();head->next = tail;tail->prev = head;}int get(int key) {if(cacheMap.count(key)){// 把node添加到头结点H// 对于双向链表, 原位置node需要修正的:// node->next->prev 和 node->prev->next// 目标位置H需要修正的:// H->next, H->next->prevNode* getNode = cacheMap[key];getNode->prev->next = getNode->next;getNode->next->prev = getNode->prev;getNode->prev = head;getNode->next = head->next;head->next = head->next->prev = getNode;return getNode->value;}else return -1;}void put(int key, int value) {if(cacheMap.count(key)){Node* getNode = cacheMap[key];getNode->value = value;// 添加到头结点getNode->prev->next = getNode->next;getNode->next->prev = getNode->prev;getNode->prev = head;getNode->next = head->next;head->next = head->next->prev = getNode;}else{if(cacheMap.size() + 1 > LRUcapacity){Node* pre = tail->prev;cacheMap.erase(cacheMap.find(pre->key));pre->prev->next = pre->next;pre->next->prev = pre->prev;// 防止内存泄漏delete pre;}cacheMap[key] = new Node(key, value);Node* getNode = cacheMap[key];// 新结点添加到头结点 (代表最近被使用)// 新结点无原位置,所以只需要修改H附近的链getNode->prev = head;getNode->next = head->next;head->next = head->next->prev = getNode;}}
};

在这里插入图片描述

题解3 STL:list+unordered_map

class LRUCache {const int cap;list<pair<int, int>> cache;unordered_map<int, decltype(cache.begin())> dict;
public:LRUCache(int capacity) : cap(capacity) {}int get(int key) {if (!dict.count(key))return -1;cache.splice(cache.cend(), cache, dict[key]);return dict[key]->second;}void put(int key, int value) {if (!dict.count(key)) {if (cache.size() == cap) {dict.erase(cache.front().first);cache.pop_front();}dict[key] = cache.emplace(cache.cend(), key, value);}else {dict[key]->second = value;cache.splice(cache.cend(), cache, dict[key]);}}
};

在这里插入图片描述

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

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

相关文章

SpringMVC+统一表现层返回值+异常处理器

一、统一表现层返回值 根据我们不同的处理方法&#xff0c;返回的数据格式都会不同&#xff0c;例如添加只返回true|false&#xff0c;删除同理&#xff0c;而查询却返回数据。 Result类 为此我们封装一个result类来用于表现层的返回。 public class Result {//描述统一格式…

publicPath:打包时的配置

vue项目&#xff0c;执行打包命令后&#xff0c;会在项目的根目录中自动创建一个文件夹dist,dist中的文件就是打包后的文件&#xff0c;只需要放到服务器中即可。 【默认情况下&#xff0c;用的绝对路径&#xff0c;需要放到服务器的根目录打开。】 如果希望放到子目录也能运行…

背靠背 HVDC-MMC模块化多电平转换器输电系统-用于无源网络系统的电能质量调节MATLAB仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; MATLAB2021版本 模型简介&#xff1a; MMC-HVDC模拟背靠背HVDC模块化多电平换流器&#xff08;MMC&#xff09;作为为整个电网供电的电能质量调节系统。因此&#xff0c;模块化多电平逆变器作为远程端转换器…

八、3d场景的区域光墙

在遇到区域展示的时候我们就能看到炫酷的区域选中效果&#xff0c;那么代码是怎么编辑的呢&#xff0c;今天咱们就好好说说&#xff0c;下面看实现效果。 思路&#xff1a; 首先&#xff0c;光墙肯定有多个&#xff0c;那么必须要创建一个新的js文件来作为他的原型对象。这个光…

SolidWorks 入门笔记03:生成工程图和一键标注

默认情况下&#xff0c;SOLIDWORKS系统在工程图和零件或装配体三维模型之间提供全相关的功能&#xff0c;全相关意味着无论什么时候修改零件或装配体的三维模型&#xff0c;所有相关的工程视图将自动更新&#xff0c;以反映零件或装配体的形状和尺寸变化&#xff1b;反之&#…

NOSQL Redis 数据持久化

Redis 数据持久化 快照方式&#xff08;RDB&#xff0c;Redis DataBase&#xff09; 全量的 在指定的时间间隔能对你的数据进行快照存储。文件追加方式&#xff08;AOF&#xff0c;Append only File&#xff09;增量 记录每次对服务器写的操作,当服务器重启的时候会重新执行这…

时间管理器:高效管理你的时间

随着社会的发展和生活节奏的加快&#xff0c;时间管理成为了人们日常生活中不可或缺的一部分。每个人都希望能够高效利用时间&#xff0c;提高工作和生活的效率。然而&#xff0c;在忙碌的生活中&#xff0c;很多人常常感到无所适从、无法合理规划自己的时间。这时&#xff0c;…

毕业设计选题之Java+springboot线上蔬菜销售与配送系统(源码+调试+开题+lw)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…

qml保姆级教程一:布局组件

&#x1f482; 个人主页:pp不会算法v &#x1f91f; 版权: 本文由【pp不会算法v】原创、在CSDN首发、需要转载请联系博主 &#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 QML系列教程 QML教程一&#xff1a;布局组件 文章目录 锚布局anchors属…

【C++】string 之 find、rfind、replace、compare函数的学习

前言 上篇文章&#xff0c;我们学习了assign、at、append这三个函数 今天&#xff0c;我们来学习find、 函数 find函数 引入 我们都知道&#xff0c;find函数可以是string类中&#xff0c;用于查找字符或者字符串的函数 也可以是&#xff0c;<algorithm>头文件中&am…

Python爬虫技术系列-01请求响应获取-urllib库

Python爬虫技术系列-01请求响应获取-urllib库 1 urllib库1.1 urllib概述1.1.1 urllib简介1.1.2 urllib的robotparser模块1.1.3 request模块1.1.4 Error1.1.5 parse模块1.1.6 百度翻译案例 1.2 urllib高级应用1.2.1Opener1.2.2 代理设置 1 urllib库 参考连接&#xff1a; https…

php导出cvs,excel打开数字超过16变科学计数法

今天使用php导出cvs&#xff0c;在excel中打开&#xff0c;某一个字段是数字&#xff0c;长度高于16位结果就显示科学计数法 超过15位的话从第16位开始就用0代替了 查询了半天总算解决了就是在后面加上"\t" $data[$key][1] " ".$value[1]."\t";…

记录一次SQL注入src挖掘过程

记录一次小白SQL注入src挖掘过程&#xff0c;其中碰到了很多问题&#xff0c;报错和解决 先是使用谷歌语法找到一个可以注入的网站 谷歌语法&#xff1a; 公司inurl:php?id 然后该公司的URL为 URL:XXXXXXXXXX/xxx.php?id1 输入测试有无注入&#xff0c;有没有waf 发现…

一探Redis究竟:超火爆入门指南,你竟然还没看?

Redis入门教程目录&#xff1a;【Redis入门教程目录】 简介 Redis是由C语言编写的开源、基于内存、支持多种数据结构、高性能的Key-Value数据库。 特性 速度快 首先Redis是将数据储存在内存中的&#xff0c;通常情况下每秒读写次数达到千万级别。其次Redis使用ANSI C编写&…

产品经理认证(UCPM)备考心得

UCPM是联合国训练所CIFAL中心颁发的产品经理证书。如今&#xff0c;ESG是推动企业可持续发展的新潮流。UCPM作为一种可持续发展证书&#xff0c;为我们带来了一套先进科学、系统全面的产品管理模式&#xff0c;是产品管理领域公认的权威证书。那么&#xff0c;如何准备这张证书…

python tempfile模块:生成临时文件和临时目录

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 tempfile 模块专门用于创建临时文件和临时目录&#xff0c;它既可以在 UNIX 平台上运行良好&#xff0c;也可以在 Windows 平台上运行良好。 tempfile 模块中常用…

GEO生信数据挖掘(三)芯片探针ID与基因名映射处理

检索到目标数据集后&#xff0c;开始数据挖掘&#xff0c;本文以阿尔兹海默症数据集GSE1297为例 目录 处理一个探针对应多个基因 1.删除该行 2.保留分割符号前面的第一个基因 处理多个探针对应一个基因 详细代码案例一删除法 详细代码案例二 多个基因名时保留第一个基因名…

进阶JS-内置构造函数

基本数据类型&#xff1a;string、number、boolean、undefined、null 引用类型:对象 其实字符串、数值、布尔等基本类型也都有专门的构造函数&#xff0c;这些我们称为包装类型。 JS中几乎所有的数据都可以基于构成函数创建。 const str andy//其实是const strnew String(a…

在windows的ubuntu LTS中安装及使用EZ-InSAR进行InSAR数据处理

EZ-InSAR&#xff08;曾被称为MIESAR&#xff0c;即Matlab界面用于易于使用的合成孔径雷达干涉测量&#xff09;是一个用MATLAB编写的工具箱&#xff0c;用于通过易于使用的图形用户界面&#xff08;GUI&#xff09;进行干涉合成孔径雷达&#xff08;InSAR&#xff09;数据处理…

开源博客项目Blog .NET Core源码学习(3:数据库操作方式)

开源博客项目Blog采用SqlSugar模块连接并操作数据库&#xff0c;本文学习并记录项目中使用SqlSugar的方式和方法。   首先&#xff0c;数据库连接信息放在了App.Hosting项目的appsettings.json中DbConfig节&#xff0c;支持在DbConfig节配置多个数据库连接信息&#xff0c;以…