LeetCode 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.get查询功能,put删除功能(如果容器内的数达到容量 capacity,则删除最久未用的那个变量),需要注意的是,这里的最久未被被查询是怎么定义的?就像

  

原本指南针这个应用是再队列的最后一位,当我打开他一次后,他就跑到前面了,另外假设容器的容量为4,我再打开一个新的应用,那么,在最后一位的计算器就要被关掉。

普通的队列可以根据元素被压入的时间进行排序,但不能访问队列中间的元素,也不能提出,哈希表可以实现查询功能,但不能实现按照元素被访问时间进行排序,如果我们把他们结合起来,组成哈希链表,既有了哈希表的查询功能,也有了链表的先后顺序功能。这里采用的是双向链表

代码如下,逻辑比较简单,主要是函数的调用。

struct DLinkedNode {//双向链表的节点int key, value;//两个存变量的int变量DLinkedNode* prev;//指向上个节点DLinkedNode* next;//指向下个节点DLinkedNode() :key(0), value(0), prev(nullptr), next(nullptr){}//初始化节点的函数DLinkedNode(int _key,int _value):key(_key),value(_value),prev(nullptr),next(nullptr){}
};
class LRUCache {
private://这个是声明变量再class外面和内部都可访问unordered_map<int, DLinkedNode*>cache;//DLinkedNode* head;//创建头节点DLinkedNode* tail;//创建尾节点int size;//统计链表内有多少个节点int capacity;//容器容量/*public: 是一个访问说明符(access specifier),它用于指定类的成员(成员变量或成员函数)在类外部是否可见和可访问。public 成员可以从任何地方被访问,包括类的外部和其他文件中的代码。*/
public:LRUCache(int _capacity) : capacity(_capacity), size(0) {//这一步是为两个变量赋值head = new DLinkedNode();//创建两个空节点tail = new DLinkedNode();head->next = tail;tail->prev = head;};int get(int key) {if (!cache.count(key))//看看这个变量在不在队列当中{return -1;}//如果在队列当中。将他提到队列头部DLinkedNode* node = cache[key];moveToHead(node);return node->value;}void put(int key, int value) {if (!cache.count(key)){//如果不存在,创建一个新节点,压入哈希表DLinkedNode* node = new DLinkedNode(key, value);cache[key] = node;// 添加至双向链表的头部addToHead(node);//++size;if (size > capacity){DLinkedNode* removed = removeTail();//删除尾部节点// 删除哈希表中对应的项cache.erase(removed->key);//使用 erase 方法来删除 map 中的单个元素// 防止内存泄漏delete removed;--size;}}else {//如果存在,先定位节点的位置DLinkedNode* node = cache[key];node->value = value;//更改值addToHead(node);//将其移动到前面}}void addToHead(DLinkedNode* node)//将节点指向头节点{node->prev = head;//指向头结点node->next = head->next;//node节点指向未插入之前头节点的下一个节点head->next -> prev = node;//调整未插入之前头结点的下一个节点,指向nodehead->next = node;}void removeNode(DLinkedNode* node) {//这个函数用于从双向链表中移除一个节点node->prev->next = node->next;//前一个结点的next指向下一个节点node->next->prev = node->prev;//后一个节点的perv}void moveToHead(DLinkedNode* Node) {//将一个节点移动到头部removeNode(Node);//删除这个节点addToHead(Node);//将这个节点移动到头节点}DLinkedNode* removeTail() {//这个函数的作用是移除链表尾部的节点并返回他的值DLinkedNode* node = tail->prev;removeNode(node);return node;}};

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

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

相关文章

Three.js——粒子效果、粒子水波、粒子组成立方体

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

DevOps后时代,构建基于价值流的平台化工程

本文来自腾讯蓝鲸智云社区用户: CanWay 平台化工程涉及双重核心意义。一方面&#xff0c;是类似利用IDE等工具提高工程师效率的平台化工程&#xff0c;如GitOps或命令行调度般便捷。然而&#xff0c;本文重点探讨的是基于价值流的平台化工程&#xff0c;尤其针对传统金融行业&a…

金融领域的AI解决方案

AI可赋能金融营销、资管、风控等领域&#xff0c;面向金融消费者、金融机构和金融监管机构&#xff0c;改善金融 市场信息对称性并提升金融交易的效率和安全性。目前&#xff0c;金融行业各机构对于安全认证和客户身份识别的需求较为迫切&#xff0c;身份识别和智能客服应用和落…

DevExpress winForm gridView 设置复选框并可多选

OptionsSelection.MultiSelect True OptionsSelection.MultiSelectMode CheckBoxRowSelect

python爬虫入门教程(二):requests库的高级用法

requests库除了基本的GET和POST请求外&#xff0c;requests库还提供了许多高级功能&#xff0c;本文将介绍其中一些常用的用法。包括&#xff1a; 会话保持&#xff08;Session&#xff09;SSL证书验证文件上传代理设置自定义HTTP适配器超时设置 请求参数 文章最开始&#x…

多线程leetcode编程题

synchronized 实现 class ReentrantTest {private int n;private volatile int flag 1;private Object lock new Object();public ReentrantTest(int n) {this.n n;}public void zero(IntConsumer printNumber) throws InterruptedException{for(int i1;i<n;){synchron…

Socket编程权威指南(一)打通网络通信的任督二脉

在网络化的今天&#xff0c;Socket已成为构建分布式系统、实现进程间通信的利器。无论是搭建Web服务器、还是开发网络游戏&#xff0c;Socket编程技能都是必不可少的武器。本文将为你娓娓道来Socket编程的精髓&#xff0c;包括基本流程概览、常用函数剖析&#xff0c;以及精彩实…

【CS.CN】优化HTTP传输:揭示Transfer-Encoding: chunked的奥秘与应用

文章目录 0 序言0.1 由来0.2 使用场景 1 Transfer-Encoding: chunked的机制2 语法 && 通过设置Transfer-Encoding: chunked优化性能3 总结References 0 序言 0.1 由来 Transfer-Encoding头部字段在HTTP/1.1中被引入&#xff0c;用于指示数据传输过程中使用的编码方式…

Locust:用Python编写可扩展的负载测试

Locust&#xff1a;简化性能测试&#xff0c;让负载模拟更直观- 精选真开源&#xff0c;释放新价值。 概览 Locust是一个开源的性能和负载测试工具&#xff0c;专门用于HTTP和其他协议的测试。它采用开发者友好的方法&#xff0c;允许用户使用普通的Python代码来定义测试场景。…

nvm,node不是内部命令,npm版本不支持问题(曾经安装过nodejs)

nvm安装后nvm -v有效&#xff0c;node指令无效 环境变量配置无问题 推荐方案 下载你需要的node版本 Index of /dist/ (nodejs.org) 下载后解压到你的nvm存储版本的位置 cmd进入切换你的使用版本&#xff08;此时你的nodejs是从网上下载的&#xff0c;npm文件是存在的&…

Maven中的DependencyManagement和Dependencies

Maven中的DependencyManagement和Dependencies Dependencies Dependencies是Maven项目中用来声明项目依赖的部分。在pom.xml文件中的<dependencies>部分&#xff0c;你可以直接列出项目所依赖的库&#xff08;artifacts&#xff09;。每个依赖通常包括以下信息&#xf…

【PythonCode】力扣Leetcode21~25题Python版

【PythonCode】力扣Leetcode21~25题Python版 前言 力扣Leetcode是一个集学习、刷题、竞赛等功能于一体的编程学习平台&#xff0c;很多计算机相关专业的学生、编程自学者、IT从业者在上面学习和刷题。 在Leetcode上刷题&#xff0c;可以选择各种主流的编程语言&#xff0c;如C…

如何将HTTP升级成HTTPS?既简单又免费的方法!

在当今数字化时代&#xff0c;网络安全已成为用户和企业关注的焦点。HTTPS作为一种更加安全的网络通信协议&#xff0c;正逐渐取代传统的HTTP成为新的标准。对于许多网站管理员和内容创作者来说&#xff0c;如何免费升级到HTTPS是一个值得探讨的问题。本文将详细介绍一些免费的…

一分钟学习数据安全—自主管理身份SSI加密技术

上篇介绍了SSI的架构。架构之后&#xff0c;我们要了解一下SSI发展的驱动力&#xff1a;加密技术。现代数字通信离不开数学和计算机科学&#xff0c;加密技术也源于此。加密技术使区块链和分布式账本得以实现&#xff0c;也使SSI成为可能。 以下我们就概览一下SSI基础架构中涉及…

前端三大主流框架

目录 1.概述 2.React 2.1.作用 2.2.诞生背景 2.3.版本历史 2.4.优缺点 2.5.应用场景 2.6.示例 2.7.未来展望 3.Vue 3.1.作用 3.2.诞生背景 3.3.版本历史 3.4.优缺点 3.5.应用场景 3.7.示例 3.8.未来展望 4.Angular 4.1.作用 4.2.诞生背景 4.3.版本历史 4…

【介绍下R-tree,什么是R-tree?】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

【Java】解决Java报错:ArrayIndexOutOfBoundsException

文章目录 引言1. 错误详解2. 常见的出错场景2.1 直接访问数组越界2.2 循环中的索引错误2.3 多维数组的错误访问 3. 解决方案3.1 检查数组长度3.2 正确使用循环3.3 多维数组的正确访问 4. 预防措施4.1 使用增强型 for 循环4.2 编写防御性代码4.3 单元测试 结语 引言 在Java编程…

mysql报错 Duplicate entry

在MySQL中&#xff0c;当你尝试执行插入&#xff08;INSERT&#xff09;或更新&#xff08;UPDATE&#xff09;操作时&#xff0c;如果目标表中存在唯一索引&#xff08;包括主键索引、唯一约束索引等&#xff09;&#xff0c;并且你要插入或更新的数据在该索引列上的值与表中已…

双网卡配置IP和路由总结

1.在网络适配器属性IPv4中设置默认网关&#xff08;记网关地址为A&#xff09;&#xff0c;将会在本地路由表中新增一条记录&#xff1a; 网络号子网掩码网关地址0.0.0.00.0.0.0A 2.如果有两个网卡&#xff08;假设一个连接内网&#xff0c;一个连接互联网&#xff09;&#…

20240607在Toybrick的TB-RK3588开发板的Android12下适配IMX415摄像头和ov50c40

20240607在Toybrick的TB-RK3588开发板的Android12下适配IMX415摄像头和ov50c40 2024/6/7 11:42 【4K/8K摄像头发热量巨大&#xff0c;请做好散热措施&#xff0c;最好使用散热片鼓风机模式&#xff01;】 结论&#xff1a;欢迎您入坑。 Toybrick的TB-RK3588开发板的技术支持不…