高阶数据结构学习——LRU Cache

news2025/1/13 6:19:11

文章目录

  • 1、了解LRU Cache(Least Recently Used缩写)
  • 2、代码实现


1、了解LRU Cache(Least Recently Used缩写)

Cache是缓存,在磁盘和内存之间,内存和寄存器之间都存在,CPU和内存之间存在三级缓存,是一个三层结构。缓存用于两个速度不一致的硬件之间,提高效率用。缓存空间有限,满了以后,新数据要进入,旧数据应当怎么办?操作系统中有个热数据概念,意思是经常被使用的数据,可能放进缓存就被拿出来,再次放进后又被拿出来使用,对应的,也有很少被使用的,也就是LRU的意思,缓存满了后,新数据进来,这些很少被使用的就出去。

设计一个LRU Cache不难,设计一个高效的,任意操作都是O(1)的LRU Cache不简单,但只有这样才能满足要求。LRU Cache最主要的操作是get和put,这两个接口必须以O(1)的时间复杂度进行。

2、代码实现

看一个题

146. LRU 缓存

在这里插入图片描述
在这里插入图片描述

看在不在,可以看地址是否在缓存中。整个操作有查找,更新,新增。虽然可以用unordered_map作为缓存,做到查找,更新都O(1),但如何找到LRU?这涉及到顺序问题,还有时间问题,这里的解决办法就是用vector或list来控制LRU,比如list,在这个list里,让处于尾部就是最久未被使用的,用一个数据就把它提到头部,list<pair<int, int>> _LRUList。但这两个结合还是做不到O(1)。因为更新时无法做到O(1),更新时可以直接修改map里的数据,但在list中更新时需要先找到这个数据再放到头部,所以不是O(1)。

以上问题的解决办法是找到key时,就同时找到key对应存储数据在list中的位置。把map中value的类型换成list的迭代器,这样map[key]中存的就是一个指针,指向list中的对应的元素,如果要使用这个数据时就用指针把它拿出来,然后头插即可。

private:
    typedef list<pair<int, int>>::iterator LtIter;
    unordered_map<int, LtIter> _hashMap;
    list<pair<int, int>> _LRUList;
class LRUCache {
public:
    LRUCache(int capacity) 
        :_capacity(capacity)
    {}
    
    int get(int key) {
        auto ret = _hashMap.find(key);
        if(ret != _hashMap.end())
        {
            //更新key对应值的位置
            LtIter it = ret->second;
            //方案1: erase + push_front 更新迭代器,原迭代器失效
            //方案2: list的splice接口可以转移节点
            _LRUList.splice(_LRUList.begin(), _LRUList, it);
            return ret->second->second;//第一个second对应迭代器,第二个second对应list的pair
        }
        else
        {
            return -1;
        }
    }
    
    void put(int key, int value) {
        //1、新增
        //2、更新
        auto ret = _hashMap.find(key);
        if(ret == _hashMap.end())//新增
        {
            if(_capacity == _hashMap.size())
            {
                pair<int, int> back = _LRUList.back();
                _hashMap.erase(back.first);
                _LRUList.pop_back();  
            }
            _LRUList.push_front(make_pair(key, value));
            _hashMap[key] = _LRUList.begin();
        }
        else//更新
        {
            LtIter it = ret->second;
            it->second = value;
            _LRUList.splice(_LRUList.begin(), _LRUList, it);
        }
    }
private:
    typedef list<pair<int, int>>::iterator LtIter;
    unordered_map<int, LtIter> _hashMap;
    list<pair<int, int>> _LRUList;
    size_t _capacity;
};

结束。

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

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

相关文章

Windows经常提示更新怎么办?一招暂停66年,绝对靠谱!

windows10/11的更新频率非常高&#xff0c;也经常会修复旧bug的同时带来一些新的bug。所以有些人不喜欢系统的自动更新&#xff0c;总想把它禁用掉。禁用系统更新的软件有很多&#xff0c;不过这些方法大多是强行禁止&#xff0c;有时候会引来一些其它的问题。 所以为了阻止Win…

“1-5-15”原则:中国联通数字化监控平台可观测稳定性保障实践

一分钟精华速览 “只知道系统有问题&#xff0c;但是找不到问题到底出在哪里”&#xff0c;这几乎是大家都面临过、或正在面临的问题。用户在投诉&#xff0c;但是我的指标都是正常的&#xff0c;到底是哪一环出问题了&#xff1f; 本文详细介绍了中国联通在智能运维领域的应用…

软考1-介绍

软考介绍&#xff1a; https://www.zhihu.com/question/530084452/answer/3230275708 软考作用&#xff1a; https://www.zhihu.com/question/29904891/answer/3181804961

(02)Mycat的安装与启动

1、 下载Mycat安装包 2、 解压缩文件拷贝到linux下 /usr/local/ 3、三个重要文件 1、schema.xml 定义逻辑库&#xff0c;表、分片节点等内容 2、rule.xml 定义分片规则 3、server.xml 定义用户以及系统相关变量&#xff0c;如端口等. 4、启动前先修改schema.xml <?x…

List 接口常用实现类底层分析

一、集合 1.1 简介 集合主要分为两组&#xff08;单列集合、双列集合&#xff09;&#xff0c;Collection 接口有两个重要的子接口 List 和Set&#xff0c;它们的实现子类都是单列集合。Map 接口的实现子类是双列集合&#xff0c;存放的是 K-V 1.2 关系图 二、Collection 接口…

听说你的爬虫被封了?

目录 前言 一、为什么会被封IP&#xff1f; 二、代理IP是什么&#xff1f; 三、代理IP的分类 1. 公共代理IP 2. 私人代理IP 四、使用代理IP的方法 1. 使用第三方库 2. 手动设置代理IP 五、常见问题及解决方法 1. 代理IP不稳定 2. 代理IP被封 六、代码实例 总结 前…

城市内涝怎么预警?万宾科技内涝积水监测仪

在城市运行过程中&#xff0c;城市内涝问题频繁出现&#xff0c;影响城市管理水平的提升&#xff0c;也会进一步减缓城市基础设施建设。尤其近几年来&#xff0c;城市内涝灾害频繁出现&#xff0c;在沿海地区内涝所带来的安全隐患成为城市应急管理部门的心头大患。城市内涝的背…

文本批量处理,一键转换HTML文件编码,释放您的繁琐工作!

亲爱的用户&#xff0c;您是否曾经为需要手动转换HTML文件编码而耗费大量时间和精力而感到困扰&#xff1f;现在&#xff0c;我们为您提供了一款强大的文本批量处理工具&#xff01;让您一键将HTML文件编码进行转换&#xff0c;轻松释放您的繁琐工作&#xff01; 首先&#xf…

RabbitMQ部署指南:使用docker部署

RabbitMQ部署指南 1.单机部署&#xff08;为例&#xff09; 我们在Centos7虚拟机中使用Docker来安装。 1.1.下载镜像 方式一&#xff1a;在线拉取 docker pull rabbitmq:3-management方式二&#xff1a;从本地加载 在课前资料已经提供了镜像包&#xff1a; 上传到虚拟机中…

JS-数组定义

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>JS-对象</title> </head><body>&l…

Centos部署清华ChatGLM3-6B详细教程

来源: AINLPer公众号&#xff08;每日干货分享&#xff01;&#xff01;&#xff09; 编辑: ShuYini 校稿: ShuYini 时间: 2023-10-03 引言 上周末&#xff0c;智谱AI在2023中国计算机大会&#xff08;CNCC&#xff09;上推出了全自研的第三代基座大模型ChatGLM3&#xff0c;在…

芯片封装技术

一、概述 封装的作用 1.3 封装类型 1.3.1 打线封装&#xff08;Wire Bonding&#xff09; 打线封装是传统的封装方式&#xff0c;具体过程是将晶圆切割为晶粒&#xff08;Die&#xff09;后&#xff0c;使晶粒贴合到相应的基板架的小岛&#xff08;LeadframePad&#xff09…

leetcode:389. 找不同

一、题目 函数原型&#xff1a;char findTheDifference(char * s, char * t) 二、思路 作者原先的思路是先将两个字符串从小到大排序&#xff0c;然后两个字符串依次比较。若出现字符串t中的元素和字符串s不相等&#xff0c;则说明该元素就是被添加的字母。 但是&#xff0c;该…

在Spring中,教你一招优雅的获取国际化语言配置的方法

在Spring中,可以将国际化语言放到HTTP请求头部,以便后端程序能够获取并解析该语言。一种常见的方式是使用Accept-Language标头字段来设置语言。下面是一个示例代码,演示如何从HTTP请求头部获取该字段的值: 在 Spring 中,可以通过 HttpServletRequest 对象获取 HTTP 头部信…

【Spring】SpringWebMVC入门

Spring Web MVC入门 什么是SpringWebMVCMVC定义什么是SpringMVC 学习SpringMVC建立连接RequestMapping注解RequestMapping使用 请求传递单个参数传递多个参数传递对象后端参数重命名传递数组传递集合传递JSON获取URL中参数pathVariable上传文件RequestPart获取Cookie/Session获…

【市场分析】Temu数据采集销售额商品量占比分析数据分析接口Api

引言 temu电商平台是一个充满活力的电商平台&#xff0c;拥有多种商品类别和数万家店铺。在这个项目中我的任务是采集平台上的大量公开数据信息。通过数据采集&#xff0c;我旨在深入了解temu电商平台的产品分布、销售趋势和文本描述&#xff0c;以揭示有趣的见解。 数据采集…

Java web(四):JSP

文章目录 一、JSP1.1 概述1.2 JSP入门1.3 JSP脚本1.4 缺点 二、EI表达式三、JSTL3.1 标签3.2 JSTL使用3.3 代码演示 四、MVC模式和三层架构五、项目实战【完成增删改查】 一、JSP 1.1 概述 JSP&#xff08;全称&#xff1a;Java Server Pages&#xff09;&#xff1a;Java 服…

【UE 材质】简单的闪闪发光材质

效果 节点 参考视频&#xff1a; https://www.bilibili.com/video/BV1uK411y737/?vd_source36a3e35639c44bb339f59760641390a8

自动化测试--验证邮件内容

场景 业务上有许多发送邮件的场景&#xff0c;发送的邮件基本上都是自动发送的&#xff0c;而且邮件内容是很重要的&#xff0c;对于邮件发没发送&#xff0c;发送的时间点对不对每次回归测试工作量太大了&#xff0c;所以考虑把这部分内容加入到自动化测试中 工具 python g…

精选8款UML图工具,闭眼入!

在现代软件开发领域&#xff0c;UML&#xff08;统一建模语言&#xff09;图是不可或缺的工具之一&#xff0c;用于可视化和通信复杂系统的结构和设计。然而&#xff0c;在选择合适的UML图工具时&#xff0c;你需要考虑多个因素&#xff0c;如项目规模、团队协作需求、功能复杂…