【LeetCode刷题-链表】--146.LRU缓存

146.LRU缓存

image-20231103194750082

方法一:哈希表+双向链表

使用一个哈希表和一个双向链表维护所有在缓存中的键值对

  • 双向链表按照被使用的顺序存储了这些键值对,靠近头部的键值对是最近使用的,而靠近尾部的键值对是最久使用的
  • 哈希表即为普通的哈希映射,通过缓存数据的键映射到其在双向链表中的位置

这样以来,我们首先使用哈希表进行定位,找出缓存项在双向链表中的位置,随后将其移动到双向链表的头部,即可在O(1)的时间内完成get或者put操作,具体方法如下:

  • 对于get操作,首先判断key是否存在

    • 如果key不存在,则返回-1
    • 如果key存在,则key对应的节点是最近被使用的节点,通过哈希表定位到该节点在双向链表中的位置,并将其移动到双向链表的头部, 最后返回该节点的值
  • 对于put操作,首先判断key是否存在

    • 如果key不存在,使用key和value创建一个新的节点,在双向链表的头部添加该节点,并将key和该节点添加进哈希表中,然后判断双向链表的节点数是否超出容量,如果超出容量,则删除双向链表的尾部节点,并删除哈希表中对应的项
    • 如果key存在,则与get操作类似,先通过哈希表定位,再将对应的节点的值更新为value,并将该节点移到双向链表的头部
class LRUCache {class DLinkedNode{int key;int value;DLinkedNode prev;DLinkedNode next;public DLinkedNode(){}public DLinkedNode(int _ket,int _value){key = _ket;value = _value;}}private Map<Integer,DLinkedNode> cache = new HashMap<Integer,DLinkedNode>();private int size;private int capacity;private DLinkedNode head,tail;public LRUCache(int capacity) {this.size = 0;this.capacity = capacity;//使用伪头部和伪尾部节点head = new DLinkedNode();tail = new DLinkedNode();head.next = tail;tail.prev = head;}public int get(int key) {DLinkedNode node = cache.get(key);if(node == null){return -1;}//如果key存在,先通过哈希表定位,再移到头部moveToHead(node);return node.value;}public void put(int key, int value) {DLinkedNode node = cache.get(key);if(node == null){//如果key不存在,创建一个新节点DLinkedNode newNode = new DLinkedNode(key,value);//添加进哈希表cache.put(key,newNode);//添加至双向链表的头部addToHead(newNode);++size;if(size > capacity){//如果超出容量,删除双向链表的尾部节点DLinkedNode tail = removeTail();//删除哈希表中对应的项cache.remove(tail.key);--size;}}else{//如果key存在,先通过哈希表定位,再修改value,并移到头部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;}}/*** Your LRUCache object will be instantiated and called as such:* LRUCache obj = new LRUCache(capacity);* int param_1 = obj.get(key);* obj.put(key,value);*/

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

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

相关文章

[shell,hive] 在shell脚本中将hiveSQL分离出去

将Hive SQL语句写在单独的.hql文件中&#xff0c; 然后在shell脚本中调用这些文件来执行Hive查询。 这样可以将SQL语句与shell脚本分离&#xff0c;使代码更加清晰和易于维护。 基本用法 以下是一个示例&#xff0c;展示如何在shell脚本中使用.hql文件执行Hive查询&#xf…

IntelliJ IDEA 安装mybaits当前运行sql日志插件在线与离线安装方法

先安装好idear 去网上找找这个安装包下载下来&#xff0c;注意版本要完全一致&#xff01; 比如&#xff1a; https://www.onlinedown.net/soft/1233409.htm手动安装离线插件方法举例 提前下载好插件的安装包 可以去网上下载这个安装包 搜索离线安装包的资源&#xff0c;包…

Java与Redis的集成以及Redis中的项目应用

一、Java连接Redis Redis与MySQL都是数据库&#xff0c;java操作redis其实跟操作mysql的过程是一样的。 1.1 导入依赖 打开IDEA&#xff0c;进入Java项目&#xff0c;导入pom依赖&#xff0c;代码如下&#xff1a; <dependency><groupId>redis.clients</gro…

(复刷) 面试题02.07.链表相交

原题链接&#xff1a;面试题02.07.链表相交 思路&#xff1a; 求相交的起始结点&#xff0c;并不是值相交&#xff0c;而是结点相交&#xff0c;那么也就代表判断条件是指针指向的位置相等即可 A、B链表长度可能不一致&#xff0c;假设他们一定有相交的结点 那么需要做的 就是…

王坚院士:云计算与 GPT 的关系,就是电和电动机的关系

无论是行业&#xff0c;还是阿里&#xff0c;都身处巨变时。已经年过六十的王坚院士&#xff0c;重回阿里&#xff0c;重回大众视野&#xff0c;今年以来&#xff0c;在多个场合都能够看到他的身影。 而每一次他的分享&#xff0c;都值得我们细细品味。 以下为王坚院士在 202…

mysql 元数据

1.概述 数据库元数据&#xff08;DatabaseMetaData&#xff09;&#xff1a;是由Connection对象通过getMetaData方法获取而来&#xff0c;主要封装了是对 数据库本身的一些整体综合信息&#xff0c;例如数据库的产品名称&#xff0c;数据库的版本号&#xff0c;数据库的URL&am…

使用OBS Browser+访问华为云OBS存储【Windows】

背景 项目中使用华为云 S3 存储,java 代码中通过华为云 OBS 提供的esdk-obs-java 来访问文件。 但是,通过 JAVA SDK 方式不太方便运维,所以我们需要一款可视化的客户端软件。 华为云 OBS 自身也提供了一款客户端软件,名为 OBS Browser+。 OBS Browser+简介 OBS Browse…

摩托车商家做展示预约小程序的作用

摩托车与电动车是人们短距离出行的主要工具&#xff0c;而其使用寿命一般是3年左右及以上、一家可能有多个&#xff0c;市场人群庞大且复购属性强&#xff0c;所以其经营商家也非常多。 如今互联网深入&#xff0c;在品牌宣传、客户获取、信息承载、营销等方面需要车辆经营商家…

网络取证-Tomcat-简单

题干&#xff1a; 我们的 SOC 团队在公司内部网的一台 Web 服务器上检测到可疑活动。为了更深入地了解情况&#xff0c;团队捕获了网络流量进行分析。此 pcap 文件可能包含一系列恶意活动&#xff0c;这些活动已导致 Apache Tomcat Web 服务器遭到破坏。我们需要进一步调查这一…

若依笔记(四):代码生成器

已知使用MyBatisPlus代码生成器可以自动生成Entity、Mapper、Service、Controller代码&#xff0c;前提是数据库中有数据表&#xff0c;生成pojo类以及对于该数据表的增删改查命令的代码&#xff0c;若依更进一步能选择表后生成代码、预览、下载&#xff0c;同时可以生产前端代…

【equals比较方法 和 内部类】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言对象比较equals方法内部类实例内部类静态内部类总结 前言 对象比较equals方法 三种比较相等方法&#xff1a; 第一种&#xff0c;如果两侧是基本数据类型&…

使用 C# 在Word中插入图表

Word中的图表功能将数据可视化地呈现在文档中。这为展示数据和进行数据分析提供了一种方便且易于使用的工具&#xff0c;使作者能够以直观的方式传达信息。要通过C#代码来实现在Word中绘制图表&#xff0c;可以借助 Spire.Doc for .NET 控件&#xff0c;具体操作参考下文。 目录…

关于GLibC

查看使用的编译器依赖glibc库位置&#xff1a; gcc --print-file-namelibc.a gcc --print-file-namelibc.so

Qt扫盲-QFont理论总结

QFont 理论总结 一、概述二、使用三、字体匹配算法 一、概述 QFont类指定用于绘制文本的时候来描述字体的工具类。QFont可以看作是对系统上一个或多个字体的查询。 当我们创建QFont对象时&#xff0c;我们可以指定希望字体具有的各种属性。Qt将使用具有指定属性的字体&#x…

初学Redis简介以及入门

&#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Linux》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;这…

详解Java经典数据结构——HashMap

Java 的 HashMap 是一个常用的基于哈希表的数据结构&#xff0c;它实现了 Map 接口&#xff0c;可以存储键值对。下面我们进行详细介绍&#xff1a; 基本结构&#xff1a;HashMap 底层是基于哈希表来实现的&#xff0c;每次插入一个键值对时&#xff0c;会先对该键进行 Hash 运…

ARM传输数据以及移位操作

3.2.2 数据传送指令 LDR/STR指令用来在寄存器和内存之间输送数据。如果我们想要在寄存器之间传送数据&#xff0c;则可以使用MOV指令。MOV指令的格式如下。 MOV {cond} {s}Rd, oprand2 MOV {cond} {s}Rd, oprand2 其中&#xff0c;{cond}为条件指令可选项&#xff0c;{s}用来表…

Android Studio创建项目后Gradle(构建)项目很慢问题解决

Android Studio创建项目后Gradle(构建)项目很慢问题解决 在使用Android Studio创建项目时&#xff0c;会自动从网上下载相关依赖。由于是访问国外服务器&#xff0c;会出现构建项目时下载依赖很慢的问题。为了解决该问题&#xff0c;需要在settings.gradle(或者settings.gradl…

Android 交叉编译openssl 、libxml2静态库

openssl: Android下openssl编译和使用&#xff08;一&#xff09;_安卓编译openssl 交叉编译 for arch in armeabi-v7a arm64-v8a-CSDN博客 libxml2: LIBXML2 2.9.11 build for Android_libxml2 android静态库_fredhurui的博客-CSDN博客

EthernetIP主站转EtherCAT协议网关采集电力变压器的 Ethernet IP 数据

怎么通过捷米JM-EIPM-ECT网关把ABB电力变压器的 Ethernet IP 数据&#xff0c;连接到欧姆龙PLC上&#xff0c;通过plc去监控电力设备的数据呢&#xff0c;下面是介绍简单的连接方法&#xff0c;采集Ethernet IP从站数据和EtherCAT协议 1 &#xff0c;捷米JM-EIPM-ECT网关连接Et…