【数据结构与算法】LRU Cache 算法实现

文章目录

  • Ⅰ. 什么是 LRU Cache
  • Ⅱ. LRU Cache 的实现
        • [146. LRU 缓存](https://leetcode.cn/problems/lru-cache/)

在这里插入图片描述

Ⅰ. 什么是 LRU Cache

LRULeast Recently Used) 是一种淘汰策略的缩写,意思是 最近最少使用,它是一种 Cache 替换算法。

​ 什么是 Cache ?狭义的 Cache 指的是位于 CPU 和主存间的快速 RAM, 通常它不像系统主存那样使用 DRAM 技术,而使用昂贵但较快速的 SRAM 技术。 广义上的 Cache 指的是位于速度相差较大的两种硬件之间, 用于协调两者数据传输速度差异的结构。除了 CPU 与主存之间有 Cache, 内存与硬盘之间也有 Cache,乃至在硬盘与网络之间也有某种意义上的 Cache ── 称为 Internet 临时文件夹或网络内容缓存等。

Cache 的容量有限,因此当 Cache 的容量用完后,而又有新的内容需要添加进来时, 就需要挑选并舍弃原有的部分内容,从而腾出空间来放新内容。 LRU Cache 的替换原则就是将最近最少使用的内容替换掉。其实,LRU 译成最久未使用会更形象, 因为该算法每次替换掉的就是一段时间内最久没有使用过的内容。

Ⅱ. LRU Cache 的实现

​ 实现 LRU Cache 的方法和思路很多,但是要保持高效实现 O(1)putget,那么使用双向链表和哈希表的搭配是最高效和经典的。使用双向链表是因为 双向链表可以实现任意位置 O(1) 的插入和删除,使用 哈希表可以实现 O(1) 的查找

​ 这分别对应到 stl 中的 listunordered_map ,其中要注意的是,为了能达到 O(1) 的效果,我们在 unordered_map 中存放的 value 值是 list 的迭代器 list<int, int>::iterator ,这样子就能快速找到链表中每个节点。

在这里插入图片描述

146. 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 ,则应该 逐出 最久未使用的关键字。

  • 函数 getput 必须以 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 <= capacity <= 3000
0 <= key <= 10000
0 <= value <= 105

代码实现:

class LRUCache {
public:LRUCache(int capacity) :_capacity(capacity){}int get(int key) {auto it = _hashMap.find(key);if(it == _hashMap.end()){return -1;}else{// 存在的话,先要将其更新到链表的首位,有两种方法// 1、使用 push_front + erase 但是容易迭代器失效问题// 2、使用 splice 函数进行转移// 这里采用第二种方法_LRUList.splice(_LRUList.begin(), _LRUList, it->second);return it->second->second;}}void put(int key, int value) {auto it = _hashMap.find(key);if(it == _hashMap.end()){// 找不到说明要新增// 需要判断一下是否需要逐出LRUif(_capacity == _hashMap.size()){// 删掉LRU_hashMap.erase(_LRUList.back().first);_LRUList.pop_back();}// 插入新增元素,记得哈希表也要存_LRUList.push_front(make_pair(key, value));_hashMap.insert(make_pair(key, _LRUList.begin()));}else{// 找到的话则更新到链表头并修改value即可it->second->second = value;_LRUList.splice(_LRUList.begin(), _LRUList, it->second);}}
private:// 容量是为了判断是否已经满了size_t _capacity;// 哈希表为查找、更新时提供O(1)的时间复杂度typedef list<pair<int, int>>::iterator LTiter;unordered_map<int, LTiter> _hashMap;// 双向链表提供O(1)的插入list<pair<int, int>> _LRUList;
};

在这里插入图片描述

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

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

相关文章

网页布局汇总

1. 盒模型 容器大小 内容大小 内边距(padding) 边框大小 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">&l…

打造海外流量矩阵,TikTok云控工具让获客更简单!

跨境获客&#xff0c;始终是无数企业主心中的一道难题。今天&#xff0c;给大家带来一款强大实用的工具——TikTok矩阵云控系统&#xff0c;帮你轻松突破流量瓶颈&#xff0c;实现高效跨境获客&#xff01; 跨国远程操控——苹果手机矩阵云控系统 在正式开始之前&#xff0c;…

MyBatis-plus 快速入门

提示&#xff1a;MyBatis-Plus&#xff08;MP&#xff09;是一个 MyBatis的增强版 文章目录 前言使用MybatisPlus的基本步骤1、引入MybatisPlus依赖代替Mybatis依赖2、定义Mapper接口并继承BaseMapper他是怎么知道哪张表&#xff0c;哪些字段呢 3、实体类注解4、根据需要添加配…

找搭子系统 搭子经济新风口 基于精准匹配的社交新生态探索

一、市场前景&#xff1a;为什么现在需要"找搭子"&#xff1f; 孤独经济爆发 超60%年轻人存在"精准陪伴"需求&#xff08;2024社交报告&#xff09; 传统社交App无法满足"非婚恋、非熟人"的中间态需求 线下活动复苏 剧本杀/飞盘等兴趣活动年增…

深入探析C#设计模式:访问者模式(Visitor Pattern)的原理与应用

引言 在软件开发中&#xff0c;设计模式为我们提供了高效、可维护的解决方案。而在众多设计模式中&#xff0c;访问者模式&#xff08;Visitor Pattern&#xff09;以其独特的结构和应用场景&#xff0c;在复杂系统中发挥着重要作用。本文将深入讲解访问者模式的定义、原理、优…

Redis核心功能实现

前言 学习是个输入的过程&#xff0c;在进行输入之后再进行一些输出&#xff0c;比如写写文章&#xff0c;笔记&#xff0c;或者做一些技术串讲&#xff0c;虽然需要花费不少时间&#xff0c;但是好处很多&#xff0c;首先是能通过输出给自己的输入带来一些动力&#xff0c;然…

RPA VS AI Agent

图片来源网络 RPA&#xff08;机器人流程自动化&#xff09;和AI Agent&#xff08;人工智能代理&#xff09;在自动化和智能化领域各自扮演着重要角色&#xff0c;但它们之间存在显著的区别。以下是对两者区别的详细分析&#xff1a; 一、定义与核心功能 RPA&#xff08;机…

多模态大语言模型arxiv论文略读(十五)

Jailbreaking GPT-4V via Self-Adversarial Attacks with System Prompts ➡️ 论文标题&#xff1a;Jailbreaking GPT-4V via Self-Adversarial Attacks with System Prompts ➡️ 论文作者&#xff1a;Yuanwei Wu, Xiang Li, Yixin Liu, Pan Zhou, Lichao Sun ➡️ 研究机构…

第1节:计算机视觉发展简史

计算机视觉与图像分类概述&#xff1a;计算机视觉发展简史 计算机视觉&#xff08;Computer Vision&#xff09;作为人工智能领域的重要分支&#xff0c;是一门研究如何使机器"看"的科学&#xff0c;更具体地说&#xff0c;是指用摄影机和计算机代替人眼对目标进行识…

【工具】Fiddler抓包

本文主要讲解如何使用Fiddler抓HTTP包&#xff0c;可通过所抓包内容分析HTTP请求/响应的细节 安装与配置 1.下载与安装 下载地址: https://www.telerik.com/fiddler/ 点击了链接后&#xff0c;跳转到以下页面&#xff1a; 点击Fiddler Classic(免费版)后&#xff0c;跳转到以…

STM32F103复用JTAG/SWD引脚为GPIO

普中-精灵1开发板&#xff0c;主芯片为STM32F103C8T6&#xff0c;4个独立按键K1~K4依次接PA15~PA12&#xff0c;按下为低电平&#xff0c;8个LED灯D1~D8&#xff0c;依次接PA0~PA7。查询手册得知&#xff1a;PA15主功能为JTDI&#xff0c;PA14为JTCK/SWCLK&#xff0c;PA13为JT…

难度偏低,25西电人工智能学院821、833、834考研录取情况

1、人工智能学院各个方向 2、人工智能学院近三年复试分数线对比 学长、学姐分析 由表可看出&#xff1a; 1、智能院25年院线相对于24年院线 全部专业下降比较多&#xff0c;其中控制科学与工程下降20分&#xff0c;计算机科学与技术下降20分&#xff0c;计算机技术[专硕]下降…

达梦数据校验系统(DMDVS):数据完整性保障的不二之选

产品概述 达梦数据校验系统(DMDVS)是一款企业级数据一致性管理平台,提供跨数据库、跨平台的数据比对与修复能力。系统采用模块化架构设计,支持静态校验、动态校验、单向校验及分布式校验四大核心模式,适用于数据迁移验证、容灾备份核查、实时同步监控等关键场景,👉更多…

【3dSwap】3D-Aware Face Swapping

文章目录 3D-Aware Face Swapping背景points贡献方法从2D图像推断3D先验通过潜在代码操纵进行人脸交换联合枢轴调整目标函数实验与二维人脸交换方法比较进一步分析3D感知人脸交换消融实验局限性3D-Aware Face Swapping 会议/期刊:CVPR 2023 作者: code:https://lyx0208.gi…

客户案例 | 日事清×初心家居:多部门协作实现新品上架自动化

1、客户背景 佛山市初心家居有限公司&#xff0c;主营家居类目&#xff0c;年营收额近亿元。初心家居有自己的家居生产工厂&#xff08;可为第三方提供生产&#xff09;&#xff0c;店内产品均为自主研发设计&#xff0c;所以新品开发也是初心家居的核心。 2、客户工作场景及需…

KWDB创作者计划—KWDB多副本集群保姆级部署

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验 Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯…

micro ubuntu 安装教程

micro ubuntu 安装教程 官网地址 : https://micro-editor.github.io 以下是在 Ubuntu 系统中安装 micro 编辑器 的详细教程&#xff1a; 方法 1&#xff1a;通过 ​apt​​ 直接安装&#xff08;推荐&#xff09; 适用于 Ubuntu 20.04 及以上版本&#xff08;官方仓库已收录…

Docker 镜像 的常用命令介绍

拉取镜像 $ docker pull imageName[:tag][:tag] tag 不写时&#xff0c;拉取的 是 latest 的镜像查看镜像 查看所有本地镜像 docker images or docker images -a查看完整的镜像的数字签名 docker images --digests查看完整的镜像ID docker images --no-trunc只查看所有的…

从零搭建微服务项目Pro(第0章——微服务项目脚手架搭建)

前言&#xff1a; 在本专栏Base第0章曾介绍一种入门级的微服务项目搭建&#xff0c;尽管后续基于此框架上实现了Nacos、Eureka服务注册发现、配置管理、Feign调用、网关模块、OSS文件存储、JSR参数校验、LogBack日志配置&#xff0c;鉴权模块、定时任务模块等&#xff0c;但由于…

VS Code下开发FPGA——FPGA开发体验提升__下

上一篇&#xff1a;IntelliJ IDEA下开发FPGA-CSDN博客 Type&#xff1a;Quartus 一、安装插件 在应用商店先安装Digtal IDE插件 安装后&#xff0c;把其他相关的Verilog插件禁用&#xff0c;避免可能的冲突。重启后&#xff0c;可能会弹出下面提示 这是插件默认要求的工具链&a…