LeetCode 热题 100_LRU 缓存(35_146_中等_C++)(哈希表 + 双向链表)(构造函数声明+初始化列表=进行变量初始化和赋值)

LeetCode 热题 100_LRU 缓存(35_146)

    • 题目描述:
    • 输入输出样例:
    • 题解:
      • 解题思路:
      • 代码实现(思路一(哈希表 + 双向链表)):
      • 部分代码解读

题目描述:

请你设计并实现一个满足 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 <= capacity <= 3000
0 <= key <= 10000
0 <= value <= 105
最多调用 2 * 105 次 get 和 put

题解:

解题思路:

思路一(哈希表 + 双向链表):
1、通过题目分析,put操作:如果key不在缓存中那我们需要进行结点的插入操作,若插入时缓存已满则先删除最久未访问的结点再插入。这里我们可以想到双向链表,头部存储最近访问结点,尾部存储最久未访问结点。get操作,若存在key则返回结点的value,这里get相当于一个查找,所以我们可以想到哈希表,这样我们就能快速的进行结点的查找和定位。

2、具体思路如下:
① 我们创建一个头结点和一个额外的尾结点来方便结点的插入和删除操作。
② 插入操作(put):我们将刚插入的元素或者最近使用的元素放在链表的头部,则尾部为最长时间未使用的元素。
     若要插入结点key时,之前存在序号为key的结点则移到链表头部。
     若要插入节点key时,之前不存在序号为key的结点,且结点数未满则插入链表头部,若结点数已满则插入后删除尾结点。

③ 获取操作(get):分析到获取我们很快能想到哈希表,因哈希表能让我们快速的进行查找操作,所以上述插入和删除时需要维护一个哈希表。
     若结点不在哈希表中则返回-1。
     若存在哈希表中则返回值,并将结点移动到头部。

力扣官方题解链接(有缓存 get() 和put () 过程图很不错)

3、复杂度分析
① 时间复杂度:对于 put 和 get 都是 O(1)。
② 空间复杂度:O(capacity),因为哈希表和双向链表最多存储 capacity+1 个元素。

代码实现(思路一(哈希表 + 双向链表)):

struct DLinkedNode{int key,value;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://存储缓存中的节点数 unordered_map<int,DLinkedNode*> cache;//head和tail方便结点的操作 DLinkedNode* head;DLinkedNode* tail;//size是当前缓存中的结点数,capacity是缓存最大的容量 int size;int capacity;public://初始化缓存,缓存容量为 _capacity,一开始缓存存入size=0个结点 LRUCache(int _capacity):capacity(_capacity),size(0){head=new DLinkedNode();tail=new DLinkedNode();head->next=tail;tail->prev=head;}//如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 int get(int key){if(!cache.count(key)){return -1;}//若存在key,则将key对应的结点移动到链表首部,先拆出来,再添加到首部 removeNode(cache[key]);addToHead(cache[key]);return cache[key]->value;} void put(int key,int value){//如果关键字 key 已经存在,则变更其数据值 valueif(cache.count(key)){removeNode(cache[key]);addToHead(cache[key]);cache[key]->value=value;//如果不存在,则向缓存中插入该组 key-value}else{DLinkedNode *newNode=new DLinkedNode(key,value);cache[key]=newNode;addToHead(newNode);++size;//如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。if(size>capacity){DLinkedNode *removed=removeTail();cache.erase(removed->key);delete removed;--size;}}}//插入链表头部void addToHead(DLinkedNode *node){node->next=head->next;node->prev=head;head->next->prev=node;head->next=node;}//断开链表尾部(需返回,用于删除哈希表中对应数据)DLinkedNode *removeTail(){DLinkedNode *node=tail->prev;tail->prev=node->prev;node->prev->next=tail;return node; }//断开结点 void removeNode(DLinkedNode* node) {node->prev->next = node->next;node->next->prev = node->prev;}
};

部分代码解读

构造函数声明+初始化列表进行变量初始化和赋值

//下方代码的用法和第一行相同,是构造函数初始化列表,对变量初始化和赋值
DLinkedNode(int _key,int _value):key(_key),value(_value),prev(nullptr),next(nullptr){} 
//构造函数
//初始化 capacity 成员变量 为传递给构造函数的参数 _capacity
//初始化 size 成员变量 为 0,表示缓存初始化时为空。
LRUCache(int _capacity):capacity(_capacity),size(0){}

LeetCode 热题 100_LRU 缓存(35_146)原题链接
欢迎大家和我沟通交流(✿◠‿◠)

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

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

相关文章

【MinIO系列】MinIO Client (mc) 完全指南

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

在跨平台开发环境中构建高效的C++项目:从基础到最佳实践20241225

在跨平台开发环境中构建高效的C项目&#xff1a;从基础到最佳实践 引言 在现代软件开发中&#xff0c;跨平台兼容性和高效开发流程是每个工程师追求的目标。尤其是对于 C 开发者&#xff0c;管理代码的跨平台构建以及调试流程可能成为一项棘手的挑战。在本文中&#xff0c;我…

2. SQL窗口函数使用

背景 窗口函数也叫分析函数&#xff0c;主要用于处理相对复杂的报表统计分析场景&#xff0c;这个功能在大多商业数据库和部分开源数据库中已经支持&#xff0c;mysql从8.0开始支持窗口函数。经典使用场景是数据错位相减的场景&#xff0c;比如求查询每年支付时间间隔最长的用…

Qt creator ,语言家功能缺失解决方法

1、找到工具->外部->配置 2、添加目录&#xff0c;双击命名语言家 3、在语言家目录下&#xff0c;添加工具 双击重命名lupdate&#xff0c;即更新翻译 %{CurrentDocument:Project:QT_INSTALL_BINS}\lupdate%{CurrentDocument:Project:FilePath}%{CurrentDocument:Projec…

软件测试之全链路压测详解

随着业务的快速发展我们日常遇到的系统性能压力问题也逐渐出现&#xff0c;甚至在部分场合会遇到一些突发的营销活动&#xff0c;会导致系统性能突然暴涨&#xff0c;可能导致我们系统的瘫痪。最近几年随着电商的各种促销活动&#xff0c;有一个词也渐渐进入我们眼帘&#xff0…

基于推理的目标检测 DetGPT

基于推理的目标检测 DetGPT flyfish detgpt.github.io 近年来&#xff0c;由于大型语言模型&#xff08;LLMs&#xff09;的发展&#xff0c;计算机视觉领域取得了重大进展。这些模型使人类与机器之间能够进行更有效、更复杂的交互&#xff0c;为模糊人类与机器智能界限的新技…

优化 invite_codes 表的 SQL 创建语句

-- auto-generated definition create table invite_codes (id int auto_incrementprimary key,invite_code varchar(6) not null comment 邀请码&#xff0c;6位整数&#xff0c;确保在有效期内…

如何在 Ubuntu 22.04 上安装以及使用 MongoDB

简介 MongoDB 因其灵活性、可扩展性、性能和生态系统而受到开发人员的青睐&#xff0c;这些都是构建和驱动现代应用程序的关键能力。通过几个配置步骤&#xff0c;你就可以在你的 Ubuntu 22.04 LTS 机器上安装 MongoDB&#xff0c;这是 Ubuntu Linux 发行版的最新长期支持版本…

小程序app封装公用顶部筛选区uv-drop-down

参考ui:DropDown 下拉筛选 | 我的资料管理-uv-ui 是全面兼容vue32、nvue、app、h5、小程序等多端的uni-app生态框架 样式示例&#xff1a; 封装公用文件代码 dropDownTemplete <template><!-- 顶部下拉筛选区封装公用组件 --><view><uv-drop-down ref&…

vulnhub靶场-matrix-breakout-2-morpheus攻略(截止至获取shell)

扫描出ip为192.168.121.161 访问该ip&#xff0c;发现只是一个静态页面什么也没有 使用dir dirsearch 御剑都只能扫描到/robots.txt /server-status 两个页面&#xff0c;前者提示我们什么也没有&#xff0c;后面两个没有权限访问 扫描端口&#xff0c;存在81端口 访问&#x…

探索多模态大语言模型(MLLMs)的推理能力

探索多模态大语言模型&#xff08;MLLMs&#xff09;的推理能力 Multimodal Large Language Models (MLLMs) flyfish 原文&#xff1a;Exploring the Reasoning Abilities of Multimodal Large Language Models (MLLMs): A Comprehensive Survey on Emerging Trends in Mult…

C++之红黑树模拟实现

目录 红黑树的概念 红黑树的性质 红黑树的查找效率 红黑树的实现 红黑树的定义 红黑树节点的插入 红黑树的平衡调整 判断红黑树是否平衡 红黑树整体代码 测试代码 上期我们学习了AVL树的模拟实现&#xff0c;在此基础上&#xff0c;我们本期将学习另一个数据结构-…

SDMTSP:粒子群优化算法PSO求解单仓库多旅行商问题,可以更改数据集和起点(MATLAB代码)

一、单仓库多旅行商问题 单仓库多旅行商问题&#xff08;Single-Depot Multiple Travelling Salesman Problem, SD-MTSP&#xff09;&#xff1a;&#x1d45a;个推销员从同一座中心城市出发&#xff0c;访问其中一定数量的城市并且每座城市只能被某一个推销员访问一次&#x…

【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?

文章目录 前言问题描述问题分析问题解决1.允许所有用户上传驱动文件2.如果是想只上传白名单的驱动 前言 该方法适合永洪BI系列产品&#xff0c;包括不限于vividime desktop&#xff0c;vividime z-suit&#xff0c;vividime x-suit产品。 问题描述 当我们连接数据源的时候&a…

决策树(理论知识3)

目录 评选算法信息增益&#xff08; ID3 算法选用的评估标准&#xff09;信息增益率&#xff08; C4.5 算法选用的评估标准&#xff09;基尼系数&#xff08; CART 算法选用的评估标准&#xff09;基尼增益基尼增益率 评选算法 决策树学习的关键在于&#xff1a;如何选择最优划…

Echarts连接数据库,实时绘制图表详解

文章目录 Echarts连接数据库&#xff0c;实时绘制图表详解一、引言二、步骤一&#xff1a;环境准备与数据库连接1、环境搭建2、数据库连接 三、步骤二&#xff1a;数据获取与处理1、查询数据库2、数据处理 四、步骤三&#xff1a;ECharts图表配置与渲染1、配置ECharts选项2、动…

Odoo 免费开源 ERP:通过 JavaScript 创建对话框窗口的技术实践分享

作者 | 老杨 出品 | 上海开源智造软件有限公司&#xff08;OSCG&#xff09; 概述 在本文中&#xff0c;我们将深入研讨如何于 Odoo 18 中构建 JavaScript&#xff08;JS&#xff09;对话框或弹出窗口。对话框乃是展现重要讯息、确认用户操作以及警示用户留意警告或错误的行…

flask-admin的modelview 实现list列表视图中扩展修改状态按钮

背景&#xff1a; 在flask-admin的模型视图&#xff08;modelview 及其子类&#xff09;中如果不想重构UI视图&#xff0c;那么就不可避免的出现默认视图无法很好满足需求的情况&#xff0c;如默认视图中只有“新增”&#xff0c;“编辑”&#xff0c;“选中的”三个按钮。 材…

低空经济的地理信息支撑:构建安全、高效的飞行管理体系

随着无人机等低空飞行器的广泛应用&#xff0c;低空空域管理的重要性日益凸显。地理信息技术作为低空空域管理的重要支撑&#xff0c;对于保障低空经济的健康发展具有不可替代的作用。 地理信息技术在低空空域管理中的作用 地理信息技术在低空空域管理中扮演着关键角色&#x…

圣诞节文化交流会在洛杉矶成功举办

洛杉矶——12月21日&#xff0c;备受期待的“圣诞节文化交流会&#xff08;Christmas Art and Cultural Exchange Fair&#xff09;”在尔湾成功举办。本次活动由M.A.D, ACSDA Youth Committee, GlowStar Art Foundation共同举办&#xff0c;此次活动以文化交流为主题&#xff…