LeetCode刷题之HOT100之LRU缓存

2024/6/21 酷暑难耐,离开空调我将不知道能否《活着》,昨天跑步感觉全身的热无法排出去,出门那种热浪一阵一阵打过来,一点风都舍不得给我。早早的来到实验室,也没多早,九点哈哈,做题啦!

1、题目描述

在这里插入图片描述

2、逻辑分析

刚看到这个题目,我看了好久,看不懂啥意思,然后去看了题解以及代码,打算跳过这题的想法在脑海里飘过三四次,好长啊代码。但是我还是看完了,就是一个redis缓存思想。该算法使用了哈希表和双链表的数据结构。LRUCache 的大致思路是使用哈希表(如 HashMap)和双链表(Doubly Linked List)来实现一个最近最少使用(Least Recently Used, LRU)缓存机制。
具体思路如下:
数据结构:
使用 HashMap 来存储键值对(key-value pairs),其中 key 是缓存项的键,value 是对应的缓存值以及该值在双链表中的节点引用。
使用双链表来维护缓存项的访问顺序。最近访问的项位于链表的头部,而最久未访问的项位于链表的尾部
初始化:
创建一个空的双链表,包含头节点(head)和尾节点(tail),它们互相指向对方,形成一个循环链表。
初始化 HashMap 用于存储键值对。
get(key) 操作:
HashMap 中查找键(key)对应的节点。
如果节点存在(即该键在缓存中),则将该节点从当前位置删除,并重新插入到链表的头部,以表示该键最近被访问过。
返回该节点的值。
如果节点不存在,则返回 -1 表示未找到。
put(key, value) 操作:
HashMap 中查找键(key)对应的节点。
如果节点存在(即该键已经在缓存中),则更新该节点的值为新的 value,并将该节点从当前位置删除,重新插入到链表的头部。
如果节点不存在(即该键不在缓存中),则需要创建一个新节点,将新节点插入到链表的头部,并在 HashMap 中添加键值对。
如果此时缓存已满(即缓存中元素的数量超过了设定的容量),则需要删除链表尾部的节点,并在 HashMap 中移除对应的键值对,以腾出空间。
维护双链表:
当有新节点插入到链表的头部时,需要更新头节点和新节点的 prevnext 指针。
当有节点从链表中删除时,需要更新该节点的前一个节点和后一个节点的 prevnext 指针。
通过这种方式,LRU 缓存能够快速地访问最近使用过的数据,并在必要时淘汰最久未使用的数据,从而保持缓存的有效性。

3、代码演示

public class LRUCache {// 双链表节点类class DLinkedNode {int key;int value;DLinkedNode prev;DLinkedNode next;// 构造无参数的DLinkedNode实例(通常用于初始化头尾节点)public DLinkedNode(){}// 构造带有key和value的DLinkedNode实例public DLinkedNode(int _key, int _value){key = _key; value = _value;}}// 使用HashMap存储key到DLinkedNode的映射private Map<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>();// 当前缓存中元素的数量 private int size;// 缓存的最大容量private int capacity;// 双链表的头尾节点,用于维护最近最少使用(LRU)顺序private DLinkedNode head, tail;// 构造函数,初始化LRUCachepublic LRUCache(int capacity) {this.size = 0;this.capacity = capacity;// 初始化头尾节点,它们之间互相指向,构成一个空链表head = new DLinkedNode();tail = new DLinkedNode();head.next = tail;tail.prev = head;}// 根据key获取缓存值public int get(int key) {DLinkedNode node = cache.get(key);// 如果节点不存在,返回-1 if(node == null){return -1;}// 节点存在,将访问过的节点移动到头部moveToHead(node);// 返回节点的值return node.value;}// 将key-value对放入缓存public void put(int key, int value) {DLinkedNode node = cache.get(key);// 如果节点不存在,创建一个新的节点并放入缓存if(node == null){DLinkedNode newNode = new DLinkedNode(key, value);cache.put(key, newNode);// 将新节点添加到头部addToHead(newNode);// 缓存元素数量加1size++;// 如果超过容量,删除尾部的节点if(size > capacity){DLinkedNode tail = removeTail();// 从HashMap中移除该节点 cache.remove(tail.key);// 缓存元素数量减1size--;}// 如果节点已存在,更新节点的值并移动到头部}else{node.value = value;moveToHead(node);}}// 将节点添加到双链表的头部private void addToHead(DLinkedNode node){node.prev = head;node.next = head.next;head.next.prev = node;head.next = node;}// 从双链表中移除一个节点private void removeNode(DLinkedNode node){node.prev.next = node.next;node.next.prev = node.prev;}// 将一个节点从当前位置移动到双链表的头部private void moveToHead(DLinkedNode node){removeNode(node);addToHead(node);}// 移除并返回双链表的尾部节点private DLinkedNode removeTail(){DLinkedNode res = tail.prev;removeNode(res);return res;}
}

4、复杂度分析

  • 时间复杂度O(1)。get和put都只需要O(1)的时间。
  • 空间复杂度O(capacity)。capacity为最大缓存容量。

拜拜啦,我知道这题下次见到还是不能完整敲出来滴,那就希望下下次可以叭,再见!

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

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

相关文章

Python联动Mysql

首先配置pip源(不然在安装库的时候会很慢!!!) pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/安装必要库: mysql.connector MySQL 连接器/ODBC 是 MySQL ODBC 驱动程序&#xff08;以前称为 MyODBC 驱动程序&#xff09;系列的名称&#xff0c;它使…

智能返利系统:探索个性化推荐技术的架构之道

智能返利系统&#xff1a;探索个性化推荐技术的架构之道 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在当今的电子商务世界中&#xff0c;购物返利系统已经…

光大证券-放量恰是入市时:成交量择时初探

核心算法 1. 在熊市中&#xff0c;各成交量时序排名出现的频次基本随排名变小而单调增大&#xff1b;在牛市中&#xff0c;各成交量时序排名出现的频次基本随排名变小而单调减少&#xff1b;而在震荡市中&#xff0c;各成交量时序排名出现的频次两头大&#xff0c;中间小&…

SpringBoot3使用Swagger3

SpringBoot3使用Swagger3 项目中的后端接口进行简单的前端展示一、依赖引入二、快速启动1.在application.yml中配置2.或者properties文件,则配置3.启动项目访问swagger 三、使用注解标注接口Swagger配置文件Swagger 注解迁移举例五种常用ApiApiOperationApiImplicitParamApiMod…

企智汇:弱电智能化项目工程项目管理系统助力企业项目管理!

在当今数字化时代&#xff0c;弱电智能化项目的复杂性和挑战性日益增加&#xff0c;高效的项目管理变得尤为重要。企智汇弱电智能化项目工程项目管理系统凭借其业务流程化、流程数据化、数据可视化、业财一体化及成本精细化等特性&#xff0c;为项目全生命周期管理提供了全面而…

MacOS设备远程登录配置结合内网穿透实现异地ssh远程连接

文章目录 前言1. MacOS打开远程登录2. 局域网内测试ssh远程3. 公网ssh远程连接MacOS3.1 MacOS安装配置cpolar3.2 获取ssh隧道公网地址3.3 测试公网ssh远程连接MacOS 4. 配置公网固定TCP地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址 5. 使用固定TCP端口地址ssh远程 …

打造卓越团队:领导以身作则的五大要点

喊破嗓子&#xff0c;不如做出样子。 领导者的命令是否能得到有效执行取决于下属是否接受&#xff0c;而下属是否接受命令很大程度上要看领导的榜样作用。如果领导都做不到&#xff0c;下属也会”上梁不正下梁歪”&#xff0c;所以领导要求下属做到的事,自己首先做到。 领导要…

AI写作如何助力大学生完成毕业论文?

近年来&#xff0c;随着科技的快速发展&#xff0c;AI已经逐渐渗透到了生活中的方方面面&#xff0c;其中也包含着学术领域。 作为学生党&#xff0c;你是否还在为期末论文&#xff0c;大学生实践报告而发愁&#xff1f; 有了这些AI写作神器&#xff0c;大学生们再也不用在期…

【Python高级编程】 综合练习-使用OpenCV 进行视频数据处理

综合练习 读取一个视频文件&#xff0c;对其进行处理后保存为一个新的视频文件。具体的处理步骤包括调整帧大小、转换为灰度图像、垂直翻转画面以及添加高斯噪声。 下面是代码的详细实现&#xff1a; import cv2 import numpy as np# 定义一个函数&#xff0c;用来给图像添加…

使用Server-Sent Events (SSE),并获取message里面的内容

什么是Server-Sent Events (SSE)? Server-Sent Events (SSE)是一种服务器推送技术&#xff0c;允许服务器向客户端&#xff08;浏览器&#xff09;发送实时消息。与WebSocket不同&#xff0c;SSE是单向通信&#xff0c;只能从服务器到客户端。SSE在HTML5中作为标准实现&#…

windows系统停止更新办法

windows系统停止更新 双击启动下载的文件 然后再回到系统-更新这里&#xff0c;选择日期就行。

C语言之链表以及单链表的实现

一&#xff1a;链表的引入 1&#xff1a;从数组的缺陷说起 &#xff08;1&#xff09;数组有两个缺陷。一个是数组中所有元素类型必须一致&#xff0c;第二是数组的元素个数必须事先指定并且一旦指定后不能更改 &#xff08;2&#xff09;如何解决数组的两个缺陷&#xff1a;数…

c++ 正则匹配得使用

标头&#xff1a;#include <regex> 相关函数&#xff1a; regex_match regex_replace regex_search 名称描述regex_match测试正则表达式是否与整个目标字符串相完全匹配。regex_replace替换匹配正则表达式。regex_search搜索正则表达式匹配项。 1. regex_search 成功搜…

『FPGA通信接口』LVDS接口(2)硬件设计

文章目录 1.LVDS原理2.xilinx器件对于LVDS的支持3.LVDS信号PCB布线要求4.传送门 1.LVDS原理 如上图所LVDS的工作原理示意图&#xff0c;其Driver驱动器由一个恒流源是LVDS发送端&#xff08;通常为 3.5mA&#xff09;驱动一对差分信号线组成。驱动状态会翻转就产生正负电压的变…

【前端】Git 常用

文章目录 一、git 配置1.1 查看系统配置1.2 查看当前用户配置1.3 查看当前git用户名1.4 查看当前git邮箱1.5 查看当前仓库配置信息1.6 修改git用户名1.7 修改git邮箱 二、git 常用命令2.1 git init2.2 git clone2.3 git status2.4 git add2.5 git commit2.5 git log2.6 git pul…

“Docker入门指南:概念与安装详解“

目录 # 概念 1. Docker常见问题 2. docker概念和安装 2.1 Docker的组成 2.2 Docker 组件及关系表 2.3 docker核心思想 2.4 docker镜像与容器两个核心概念 2.5 容器概念图 2.6 docker核心技术 2.6.1 镜像 (Image) 概述 关系 示例 2.6.2 容器 (Container) 概述 关…

C# 控件-ComboBox

ComboBox 是一个下拉列表控件&#xff0c;它允许用户从预定义的选项中进行选择&#xff0c;或者输入自定义的文本。以下是如何理解和快速掌握 ComboBox 控件的几个关键点&#xff1a; 创建和初始化 ComboBox: ComboBox comboBox new ComboBox();添加项: 直接添加字符串项&a…

android在线阅读代码网站

android在线阅读代码社区&#xff1a; Android 1.6 到 Android 10 的源码&#xff1a; Android OS 在线源代码 - https://www.androidos.net.cn10.0.0_r6 - Android社区 - https://www.androidos.net.cn/ AndroidXRef https://cs.android.com/ https://cs.android.com/android…

抖音小程序中如何预览一组图片

1.使用tt.previewImage api 语法 tt.previewImage(options)具体使用 **需要注意imgUrl必须是http/https的线上路径&#xff0c;不支持本地路径和base64格式的图片**var imgUrl this.data.imgUrltt.previewImage({urls: [imgUrl], //需要预览的图片http链接列表&#xff0c;…

Mongodb UPDATE使用$sort将数组重新排序

学习mongodb&#xff0c;体会mongodb的每一个使用细节&#xff0c;欢迎阅读威赞的文章。这是威赞发布的第74篇mongodb技术文章&#xff0c;欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题&#xff0c;欢迎在文章下面点个赞&#xff0c;或者关…