问题链接

146.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 ,则应该 逐出 最久未使用的关键字。

函数 getput 必须以 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 <= 10^5
  • 最多调用 2 * 10^5getput

问题解答

要解决LRU(最近最少使用)缓存问题,我们需要设计一个数据结构,支持在O(1)平均时间复杂度内完成getput操作。核心思路是结合哈希表(快速查找)和双向链表(维护使用顺序)。

解题思路

  1. 数据结构选择

    • 哈希表(HashMap):存储键到双向链表节点的映射,实现O(1)时间复杂度的查找。
    • 双向链表:维护节点的使用顺序,最近使用的节点放在链表头部,最久未使用的节点放在尾部,支持O(1)时间复杂度的插入、删除和移动操作。
    • 虚拟头节点和虚拟尾节点:简化边界处理(如插入第一个节点或删除最后一个节点时无需判断null)。
  2. 核心操作

    • get(key):若键存在,将对应节点移到链表头部(标记为最近使用)并返回值;否则返回-1。
    • put(key, value):若键存在,更新值并将节点移到头部;若键不存在,创建新节点插入头部,若容量超限,删除链表尾部节点(最久未使用)并从哈希表中移除对应键。

代码实现

import java.util.HashMap;
import java.util.Map;class LRUCache {// 双向链表节点static class Node {int key;int value;Node prev;Node next;public Node(int key, int value) {this.key = key;this.value = value;}}private final Map<Integer, Node> cache; // 哈希表:key -> 节点private final Node head; // 虚拟头节点private final Node tail; // 虚拟尾节点private final int capacity; // 缓存容量public LRUCache(int capacity) {this.capacity = capacity;cache = new HashMap<>(capacity);// 初始化虚拟节点并连接head = new Node(-1, -1);tail = new Node(-1, -1);head.next = tail;tail.prev = head;}public int get(int key) {if (!cache.containsKey(key)) {return -1; // 键不存在,返回-1}Node node = cache.get(key);moveToHead(node); // 访问后移到头部(最近使用)return node.value;}public void put(int key, int value) {if (cache.containsKey(key)) {// 键存在,更新值并移到头部Node node = cache.get(key);node.value = value;moveToHead(node);} else {// 键不存在,创建新节点Node newNode = new Node(key, value);cache.put(key, newNode);addToHead(newNode); // 插入头部// 若容量超限,删除尾部节点(最久未使用)if (cache.size() > capacity) {Node tailNode = removeTail();cache.remove(tailNode.key);}}}// 将节点移到头部(先删除再插入头部)private void moveToHead(Node node) {removeNode(node);addToHead(node);}// 从链表中移除节点private void removeNode(Node node) {node.prev.next = node.next;node.next.prev = node.prev;}// 将节点插入到头部(虚拟头节点之后)private void addToHead(Node node) {node.next = head.next;node.prev = head;head.next.prev = node;head.next = node;}// 移除尾部节点(虚拟尾节点之前的节点)并返回private Node removeTail() {Node res = tail.prev;removeNode(res);return res;}
}

复杂度分析

  • 时间复杂度getput操作均为O(1)。哈希表保证了键的查找为O(1),双向链表保证了节点的插入、删除和移动为O(1)。
  • 空间复杂度:O(capacity),最多存储capacity个键值对。

该实现通过哈希表和双向链表的结合,高效满足了LRU缓存的约束,适用于需要频繁访问且对性能要求较高的场景。

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

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

相关文章

MySQL超大数据量查询与删除优化

引言 在处理TB级数据时&#xff0c;传统SQL操作可能导致性能崩溃。本文揭示MySQL超大数据量场景下的核心优化策略&#xff0c;通过生产环境案例展示如何将亿级数据删除耗时从8小时压缩至8分钟&#xff0c;并附完整监控方案与容灾措施。 深度剖析海量数据操作痛点 1. 传统删除操…

【内存管理】常用的页表映射函数

1、pgd_addr_end 根据当前虚拟地址 addr 和目标结束地址 end&#xff0c;计算当前 PGD 项 能够覆盖的最大虚拟地址范围的结束地址 next。 如果 addr 和 end 跨越多个 PGD 项&#xff08;即 end 超出当前 PGD 项的地址范围&#xff09;&#xff0c;则返回当前 PGD 项的地址边界。…

XR数字融合工作站赋能新能源汽车专业建设的创新路径

XR数字融合工作站作为集PC、VR、MR技术于一体的软硬件集成平台&#xff0c;凭借其多维交互、虚实融合、智能管理等特性&#xff0c;为新能源汽车专业的教学改革与创新提供了全新解决方案。一、教学场景革新&#xff1a;构建沉浸式、互动化学习环境XR数字融合工作站通过多形态拼…

C语言通用链表终章:优雅的收尾 - 清空与销毁

各类资料学习下载合集 ​https://pan.quark.cn/s/8c91ccb5a474​ 经过前面的学习,我们已经从零构建了一个功能强大的通用链表,它能自如地进行节点的插入和删除。我们的“数据火车”已经可以驰骋在内存的世界里。然而,旅途终有终点,当火车完成任务后,如何安全、彻底地让…

MATLAB R2025a安装配置及使用教程(超详细保姆级教程)

文章目录前言什么是MATLAB&#xff1f;了解这款数据分析利器matlab安装前准备工作MATLAB R2025a下载完整MATLAB R2025a安装步骤MATLAB进阶应用技巧前言 全网最新最全的MATLAB R2025a安装教程来了&#xff01;2025年版本完整图文指南&#xff0c;包含软件下载、详细安装、密钥激…

在Mybatis plus中如何使用自定义Sql

在演示UpdateWrapper的案例中&#xff0c;我们在代码中编写了更新的SQL语句&#xff1a;Test void testUpadateWrapper(){List<Long> ids List.of(1L,2L,4L);//生成SQLUpadateWrapper<User> wrapper new UpdateWrapper<User> ().setSql("balance balan…

Deepoc科技之暖:智能助盲设备如何为视障家人点亮生活

作为一名视障人士的家属&#xff0c;我们或许都经历过这样的时刻&#xff1a;看着亲人在书架前摸索&#xff0c;却无法独自获取文字信息&#xff1b;担心他们外出时遇到障碍物或交通危险&#xff1b;心疼他们因找不到日常物品而不得不一次次求助。这些细微的日常困境&#xff0…

大模型食材识别技术革新:AI重构精准营养管理

随着健康意识的提升&#xff0c;饮食管理需求激增&#xff0c;但传统手动记录易出错、效率低。大模型食材识别技术的突破&#xff0c;让AI通过多模态输入精准识别食材种类与重量&#xff0c;结合营养数据库&#xff0c;系统可快速生成营养报告&#xff0c;实现从“经验驱动”到…

使用 Altair RapidMiner 将机器学习引入您的 Mendix 应用程序

Altair RapidMiner 使机器学习更加容易&#xff1a;无论您喜欢使用 Python 编码&#xff0c;还是在 Workflow Studio 中进行可视化工作&#xff0c;Altair AI Cloud 都能为团队提供快速构建和部署 ML 模型的工具。 将机器学习与 Mendix 集成很简单&#xff1a;通过 Mendix 的低…

EasyExcel:快速读写Excel的工具类

EasyExcel&#xff1a;快速读写Excel的工具类 项目介绍 ​EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。 他能让你在不用考虑性能、内存的等因素的情况下&#xff0c;快速完成Excel的读、写等功能。 pom地址 ‍ <!--exel--> <depe…

WSL Ubuntu Docker 代理自动配置教程

WSL Ubuntu Docker 代理自动配置教程 WSL Ubuntu Docker 代理自动配置教程 背景说明 在 WSL2 环境下使用 Docker 时&#xff0c;由于网络环境限制&#xff0c;经常需要通过 Windows 主机上的代理来访问 Docker Hub。但每次 Windows 重启后&#xff0c;WSL 获取到的主机 IP 地址…

踩坑实录:Django继承AbstractUser时遇到的related_name冲突及解决方案

一、问题现象分析 咱们在用Django开发时&#xff0c;有时候需要扩展用户模型&#xff0c;就会去继承AbstractUser。但这么做的时候&#xff0c;要是没处理好groups和user_permissions这两个多对多字段的反向查询名称&#xff0c;就会遇到这样的报错&#xff1a;主要就是这种错误…

push pop 和 present dismiss

push/pop 和 present/dismiss 文章目录push/pop 和 present/dismiss前言push / poppresent普通的present多层present多层present后的父子关系问题多层弹出会遇到的问题showViewController 和 showDetailViewControllershowViewControllershowDetailViewControllerdismiss模态化…

服务器异常负载排查手册 · 隐蔽进程篇

适用范围 适用于 Linux 3.10 生产环境&#xff0c;发现 load 高但用户态 CPU 接近 0 % 的场景。1. 现场冻结目标&#xff1a;在 rootkit 干预前保存易失数据。#!/bin/bash # freeze.sh TS$(date %s) mkdir -p /srv/ir/${TS} cd /srv/ir/${TS}# 1.1 进程树&#xff08;busybox 静…

2024理想算法岗笔试笔记

要理解指令微调&#xff08;Instruction Tuning&#xff09;&#xff0c;需要先将其置于大语言模型&#xff08;LLM&#xff09;的训练框架中 —— 它并非模型训练的起点&#xff0c;而是针对 “让模型更懂人类需求” 的关键优化步骤。简单来说&#xff0c;指令微调是通过让模型…

Oracle 11g离线安装依赖包完整解决方案

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;Oracle 11g是一款广泛使用的关系型数据库管理系统&#xff0c;在离线环境下安装时需依赖多个系统库和工具。本“oracle11g依赖包”压缩文件包含了在CentOS 7.7上安装Oracle 11g可能缺失的关键依赖RPM包&#xf…

VBA数据结构选型:效率差5倍的生死抉择

VBA性能生死局&#xff1a;Dictionary与Collection效率差5倍&#xff01;90%开发者用反血亏“你以为Collection是VBA的‘轻量级选手’&#xff1f;大错特错&#xff01;实测数据显示&#xff1a;在10万级数据循环中&#xff0c;Dictionary的查询速度比Collection快5倍&#xff…

电机控制(四)-级联PID控制器与参数整定(MATLABSimulink)

PID算法 普通PID&#xff08;Proportional-Integral-Derivative&#xff09; 通过比例&#xff08;P&#xff09;、积分&#xff08;I&#xff09;和微分&#xff08;D&#xff09;三项来进行控制 比例项&#xff08;P&#xff09;&#xff1a;根据当前误差&#xff08;目标值…

数据结构深度解析:二叉树的基本原理

在数据结构体系中&#xff0c;树是一种重要的非线性层次结构&#xff0c;它通过 “节点” 与 “边” 的连接关系&#xff0c;模拟了现实世界中树的分支结构&#xff0c;能够高效地解决数据的查找、插入、删除等问题。而二叉树作为树结构中最简单、应用最广泛的类型&#xff0c;…

【React】Ant Design 5.x 实现tabs圆角及反圆角效果

需要实现的效果实现思路 利用tab页的before和after属性&#xff0c;添加tab页前后的圆弧属性&#xff0c;同时使用tab页的shadow阴影填充右下角的圆弧空缺部分。<TabsonChange{onChange}type"card"items{getTabItems()}/>.ant-tabs-nav{margin: 0;.ant-tabs-na…