当前位置: 首页 > news >正文

算法----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 <= capacity <= 3000
0 <= key <= 10000
0 <= value <= 105
最多调用 2 * 105 次 get 和 put

解决思路

使用Map加双链表实现即可,参考Java里LinkedHashMap

解决方法

    class Node(key: Int, value: Int) {var pre: Node? = nullvar nex: Node? = nullvar value: Intvar key: Intinit {this.value = valuethis.key = key}}class LRUCache(capacity: Int) {var map = mutableMapOf<Int, Node>()private var dumpHead: Node = Node(-1, -1)private var dumpTail: Node = Node(-1, -1)var mCapability = capacityinit {dumpHead.nex = dumpTaildumpTail.pre = dumpHead}fun get(key: Int): Int {val value = map.getOrDefault(key, null)if (value != null) {updateNodeToHeadNext(map[key])}return value?.value ?: -1}fun put(key: Int, value: Int) {if (map.containsKey(key)) {updateNodeToHeadNext(map[key])map[key]!!.value = value} else {val node = Node(key, value)dumpHead.nex!!.pre = nodenode.nex = dumpHead.nexdumpHead.nex = nodenode.pre = dumpHeadmap[key] = node}while (map.size > mCapability) {dumpTail.pre?.let {it.pre!!.nex = dumpTaildumpTail.pre = it.premap.remove(it.key)}}}private fun updateNodeToHeadNext(find: Node?) {if (find != null) {find.nex!!.pre = find.prefind.pre!!.nex = find.nexdumpHead.nex!!.pre = findfind.nex = dumpHead.nexdumpHead.nex = findfind.pre = dumpHead}}}

偷懒版:

    class CacheMap(initialCapacity: Int, loadFactor: Float, accessOrder: Boolean) :LinkedHashMap<Int, Int>(initialCapacity, loadFactor, accessOrder) {private val initC = initialCapacityoverride fun removeEldestEntry(eldest: MutableMap.MutableEntry<Int, Int>?): Boolean {return size > initC}}class LRUCache(capacity: Int) {var map = CacheMap(capacity, 0.5f, true)fun get(key: Int): Int {return map.getOrDefault(key,-1)}fun put(key: Int, value: Int) {map[key] = value}}

总结

1.事非经过不知难。 本以为很简单 结果还是一个小时下来了

2.哎 之前面试过这个题 但是自己直接说用LinkedHashMap

3.为了保证时间复杂度为O(1),Map 里 value 为 Node
方便对Node进行调整。

相关文章:

算法----LRU缓存机制

题目 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#xff0c;否则返…...

基于springboot+vue的旅游系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...

什么是堆栈和队列?如何实现它们?

堆栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;是两种常见的线性数据结构&#xff0c;用于组织和管理数据。它们分别具有不同的特点和用途。本文将详细解释堆栈和队列的概念、特点以及如何实现它们。 堆栈&#xff08;Stack&#xff09; 什么是堆栈&…...

编译器自动生成的构造函数

背景 作为一个C小白&#xff0c;最近在看深度解析对象模型的时候&#xff0c;发现一个很久以来的认知错误&#xff1a;编译器会为没有定义构造函数的class生成一个默认构造函数。其实这个观点是错误的&#xff0c;编译器只会在四种情况下生成。 相关知识 一定要明确一个事情…...

SpringSecurity - 认证与授权、自定义失败处理、跨域问题、认证成功/失败处理器

SpringSecurity 文章目录 SpringSecurity一、 简介二、快速入门2.1 maven坐标2.2 访问请求 三、认证与授权3.1 认证3.1.1 登录检验流程3.1.2 SpringSecurity 完整流程3.1.3 认证流程详解3.1.4 校验3.1.5 要解决的问题3.1.6 准备工作3.1.7 实现3.1.7.1 数据库校验用户3.1.7.1.1 …...

自定义映射resultMap

自定义映射resultMap 自定义映射resultMap 自定义映射resultMapresultMap处理字段和属性的映射关系字段名和属性名不一致的情况&#xff0c;如何处理映射关系?1、为查询的字段设置别名&#xff0c;和属性名保持一致2、核心配置文件(mybatis-config.xml)中设置一个全局配置3、使…...

Android修行手册 - Android Studio去掉方法参数提示、变量类型提示、方法引用Usage提示

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…...

【车载开发系列】ECU Application Software程序刷新步骤

【车载开发系列】ECU Application Software程序刷新步骤 ECU Application Software程序刷新步骤 【车载开发系列】ECU Application Software程序刷新步骤一. Boot Software&#xff08;引导软件&#xff09;1&#xff09;boot manager&#xff08;启动管理器&#xff09;2&…...

inject和provide的使用

官网介绍用法 V2.2.0 新增的方法 类型 provide&#xff1a;Object | () > Object inject&#xff1a;Array<string> | { [key: string]: string | Symbol | Object }介绍 这对选项需要一起使用&#xff0c;以允许一个祖先组件向其所有子孙后代注入一个依赖&#xff…...

2023年中国研究生数学建模竞赛D题

一、背景介绍 2021年9月22日&#xff0c;中共中央国务院正式发布《关于完整准确全面贯彻新发展理念做好碳达峰碳中和工作的意见》&#xff08;以下简称《意见》&#xff09;&#xff0c;明确了中国双碳行动的顶层设计。 我国是世界上最大的发展中国家&#xff0c;为实现中华民…...

Unity制作曲线进度条

unity制作曲线进度条 大家好&#xff0c;我是阿赵。   在使用Unity引擎做进度条的时候&#xff0c;有时会遇到一个问题&#xff0c;如果进度条不是简单的横向、纵向或者圆形&#xff0c;而是任意的不规则形状&#xff0c;那该怎么办呢&#xff1f;比如这样的&#xff1a; 一…...

面试:C++ 11 智能指针

查询内存泄露方法 啥是内存泄露 内存泄露在维基百科中的解释如下&#xff1a; 在计算机科学中&#xff0c;内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失&#xff0c;而是应用程序分配某段内存后&#xff0c;由于设计错误&…...

设计模式——3. 抽象工厂模式

1. 说明 抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种创建一组相关或依赖对象的方式,而无需指定它们的具体类。抽象工厂模式是工厂模式的扩展,它关注于创建一组相关的对象家族,而不仅仅是一个单一的对象。 抽象工厂模式通常涉及以下几个角…...

vscode 无法使用 compilerPath“D:.../bin/arm-none-eabi-g++.exe”解析配置。

最近在使用vscode搭建ODrive STM32开发环境,依次安装了以下内容: 1.Python3: 用于运行工程构建脚本 2.ST-Link/V2 Drivers: STLink/v2编程器的驱动 3.Visual Studio Code: 轻量级但功能强大的源代码编辑器 …...

Vue.js入门模板语法[上] 及Vue.js实现购物车---详细讲解

前言 前面我们学习了Vue的基础入门&#xff0c;接下来我们学习有关Vue的模板语法&#xff0c;学习Vue语法能提高我们的前端开发效率 Vue.js 使用了基于 HTML 的模板语法&#xff0c;允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML &a…...

windows下gvim的配置

一、vim配置文件 "查看自己的vimrc所在的目录 "在命令模式下 :echo $MYVIMRC"打开自己的vimrc文件 "在命令模式下 :e $MYVIMRC 二、排版 "查看自己当前的字体及大小 "在命令模式下 :set guifont?"设置默认的字体为仿宋_GB2312&#xff…...

基于复旦微的FMQL45T900全国产化ARM开发开发套件(核心板+底板)

TES745D是我司自主研制的一款基于上海复旦微电子FMQL45T900的全国产化ARM核心板&#xff08;模块&#xff09;。该核心板将复旦微的FMQL45T900&#xff08;与XILINX的XC7Z045-2FFG900I兼容&#xff09;的最小系统集成在了一个87*117mm的核心板上&#xff0c;可以作为一个核心模…...

Leetcode Top100(23)环形链表

给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;索…...

线性代数基础-行列式

一、行列式之前的概念 1.全排列&#xff1a; 把n个不同的元素排成一列&#xff0c;称为n个元素的全排列&#xff0c;简称排列 &#xff08;实际上就是我们所说的排列组合&#xff0c;符号是A&#xff0c;arrange&#xff09; 2.标准序列&#xff1a; 前一项均小于后一项的序列…...

RT-Thread(学习)

RT-Thread是一款完全由国内团队开发维护的嵌入式实时操作系统&#xff08;RTOS&#xff09;&#xff0c;具有完全的自主知识产权。经过16个年头的沉淀&#xff0c;伴随着物联网的兴起&#xff0c;它正演变成一个功能强大、组件丰富的物联网操作系统。 RT-Thread概述 RT-Threa…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...