Leetcode NO.146 lru-cache LRU Cache 最近最少使用实现

图解LeetCode146:LRU cache 文章目录思考过程代码实现总结 这是LeetCode中第146号题目,不多说,这也是一个准备面试的同学必备的一道题目,出镜率非常高。 那么什么是LRU cache呢,假设有一个大小为6的数组,最开始保存的是[1,2,3,4,5,6],如果这个数组就是LRU cache的话会有这样的性质: 一图胜千言,现在你应该明白什么是LRU cache了吧。 LRU的全称是Least Recently Used... 阅读详情

1.问题描述

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
实现 LRUCache 类:

LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

注意:

你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

2.测试用例

示例 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

3.提示

  • 1 <= capacity <= 3000

  • 0 <= key <= 10000

  • 0 <= value <= 105

  • 最多调用 2 * 105 次 get 和 put

4.代码

1.继承LinkedHashMap实现
code
public class LRU_Cache_With_LinkedHashMap extends LinkedHashMap<Integer, Integer> {


    private int capacity;

    public LRU_Cache_With_LinkedHashMap(int initialCapacity) {
        /**
         * initialCapacity 容量
         * loadFactor 扩容因子
         * accessOrder false 不删除,
         */
        super(initialCapacity, 0.75f, true);
        this.capacity = initialCapacity;
    }


    @Override
    public Integer get(Object key) {
        return super.get(key) == null ? -1 : super.get(key);
    }

    @Override
    public Integer put(Integer key, Integer value) {
        return super.put(key, value);
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
        // return true 的话,如果map容量已满,允许新的插入,并且移除老的数据
        //这里是实现,容量满了以后,最老的数据删除的操作
        return size() > capacity;
    }
}
复杂度
1.时间 O(1)

2.空间 O(capacity)
2.HashMap && DoubleLinklist
code
public class LRUCache {

    private int capacity;
    private int size;
    private DoubleListNode startSentinel;
    private DoubleListNode endSentinel;
    private HashMap<Integer, DoubleListNode> hashMap;


    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.size = 0;
        hashMap = new HashMap<>(capacity);
        startSentinel = new DoubleListNode();
        endSentinel = new DoubleListNode();
        startSentinel.next = endSentinel;
        endSentinel.pre = startSentinel;
    }

    class DoubleListNode {
        private Integer key;
        private Integer val;
        private DoubleListNode pre;
        private DoubleListNode next;

        public DoubleListNode() {
        }

        public DoubleListNode(Integer key, Integer val) {
            this.key = key;
            this.val = val;
        }

        @Override
        public String toString() {
            return "val=" + val;
        }
    }

    @Override
    public String toString() {
        return "LRUCache{" +
                "hashMap=" + hashMap +
                '}';
    }




    public Integer get(Integer key) {
        DoubleListNode node = hashMap.get(key);
        //获取不到返回-1
        if (node == null) {
            return -1;
        }
        //移动数据到链表结尾
        moveToTail(node);
        return node.val;
    }

    public void put(Integer key, Integer value) {
        DoubleListNode node = hashMap.get(key);
        if (node == null) {
            //判断当前size 和 capacity 的大小
            if (size < capacity) {
                //size ++
                size++;
                //新增节点
                node = new DoubleListNode(key, value);
                //移动新节点到链表末尾
                addToTail(node);
                hashMap.put(key, node);

            } else {
                //删除头结点
                DoubleListNode rmNode = removeNode(startSentinel.next);
                hashMap.remove(rmNode.key);
                //移动新节点到链表尾部
                DoubleListNode newNode = new DoubleListNode(key, value);
                addToTail(newNode);
                //添加结点到hashmap
                hashMap.put(key,newNode);
            }
        } else {
            //更新值
            node.val = value;
            //放到尾部
            moveToTail(node);
        }
    }


    /**
     * 移动节点到链表尾部
     *
     * @param node
     */
    private void moveToTail(DoubleListNode node) {
        removeNode(node);
        addToTail(node);
    }

    /**
     * 添加结点到双向链表尾部
     *
     * @param node node
     */
    private void addToTail(DoubleListNode node) {
        node.next = endSentinel;
        node.pre = endSentinel.pre;
        endSentinel.pre.next = node;
        endSentinel.pre = node;
    }

    /**
     * 移除节点
     * @param node node
     * @return re
     */
    private DoubleListNode removeNode(DoubleListNode node) {
        node.pre.next = node.next;
        node.next.pre = node.pre;
        return node;
    }

}
复杂度
1.时间 O(1)

2.空间 O(capacity)
【leetcode】(python)146. LRU Cache最近最少使用缓存 最近最少使用缓存DescriptionExample题意解体思路code 146. LRU Cache Medium Description Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and pu... 阅读详情

相关推荐

LRUCache.java

lru-1缓存算法,java简单实现

spring boot自定义缓存,使用fifo,lru,lfu算法实现

目录概述功能实现项目结构1.创建Cahce接口2.创建基础缓存类3.实现FIFO,LFU,LRU三种淘汰算法3.1、FIFO(先进入先淘汰)算法3.2 LRU(最近最少使用)算法3.3 LFU(历史访问率最低)算法4.定义缓存同步,日志4.1定义同步缓存4.2 定义日志缓存5.定义缓存注解,缓存切面等核心实现5.1 定义缓存注解5.2 定义缓存常量5.3 定义缓存异常类5.4 定义Vo缓存实体5.5 定义缓存工厂类5.6 定义缓存切面6.测试缓存6.1 定义测试实体6.2 定义测试业务6.3 定义测试接口6

qq_26751319的博客 1567

ollama接入图像识别大模型

ollama接入图像识别大模型

qq_36437991的博客 2075

SpringBootCache的使用(Redis实现)

众所周知,缓存一般在内存中存储,cpu对内存的调度效率要优于硬盘(时间快)我们通常使用空间换取时间,达到某种程度的时空平衡于是一般来讲使用缓存可以提高效率—>提升性能我这次使用缓存是目的是将数据库字典类查询的结果放入缓存,以便于提高字典类使用时查询的效率(注:我所用到的字典类一般不会更新,数据量也不大,占用内存不多,大多用于查询的操作,适合用做缓存,可以大大减少数据库的压力,在一定程度上提升性能)

weixin_47224121的博客 1029

InSAR_ISCE软件数据处理流程之:利用哨兵数据获取2015年尼泊尔地震同震形变场

ISCE软件数据处理流程之:利用哨兵数据获取2015年尼泊尔地震同震形变场 ISCE软件做干涉只需要将数据准备好,并配置好insarApp.xml文件即可进行。 一、数据准备 1、SAR数据获取 本利中使用的数据为欧空局提供的sentinel-1A/B数据,可从阿拉斯加数据服务器上下载,具体下载方法可参考: 哨兵数据下载方法. 2、哨兵卫星轨道文件下载 哨兵数据处理除了需要SAR影像外,还需提供轨道参数文件,可从https://qc.sentinel1.eo.esa.int/aux_poeorb/下载。下载

weixin_42128764的博客 1万+

Android 车载应用开发与优化(1) - CarLauncher 核心功能与动态集成探秘

本文深入探讨了Android车载应用开发中CarLauncher的核心功能与实现原理。作为车载系统的“脸面”,CarLauncher不仅提供应用入口,更通过动态集成技术将地图、音乐等关键信息嵌入桌面,以保障驾驶安全与体验。文章详细解析了其源码结构、权限配置、应用启动机制以及基于Activity嵌入的动态集成黑魔法,为开发者提供了从基础认识到高级优化的完整指南。

weixin_29239279的博客 283

Spring Boot整合Redis缓存并使用注解

在Spring Boot应用程序中,您可以使用Spring Cache库与Redis缓存进行集成,以提高应用程序的性能和响应速度。Spring Cache库提供了一组注解,包括@Cacheable@CachePut和,可以方便地将方法的返回值缓存到Redis中,并根据需要进行刷新和清除。本篇博客将向您展示如何在Spring Boot项目中整合Redis缓存,并使用注解来管理缓存操作。

算命de博客 1960

Clipper库中文帮助文档

引言: 第一次接触Clipper,主要是想用来处理DXF中的图形,网上也有博友翻译过,但是可惜打不开,好像那个网站https://love2.io凉凉了,但是优快云上也有博友分享了CHM,看着只剩3个下载币的我好无奈,一怒之下花费两天的时间将英文CHM也翻译了一遍,主要还是想在翻译的同时好好的理解Clipper,为使用打下坚实的基础。当然我也会无私的奉献出来。 简单的认识一下Clipper:...

zefllj的博客 3422

SpringBoot缓存应用实践

*** 缓存提供者接口**//*** 查询缓存** @param key 缓存键 不可为空**//*** 查询缓存** @param key 缓存键 不可为空* @param function 如没有缓存,调用该callable函数返回对象 可为空**//*** 查询缓存** @param key 缓存键 不可为空* @param function 如没有缓存,调用该callable函数返回对象 可为空。

z_ssyy的博客 873

MIT 6.824分布式 LAB4A:ShardCtrler

lab 4要求实现一个使用raft共识算法的分片存储系统。而在lab 4a中,我们仅需实现分片控制器的功能。lab4中的分片存储系统有多个分片,这些数据分布在众多分片上,而每个分片都对应着一个集群组,可能一个集群组负责多个分片,一个集群组内的所有服务器都会使用raft共识算法进行状态的复制。而本实验的重点为分片控制器,主要负责的工作是对集群组和分片之间关系的管理,我们仅需在/src/shardctrler文件夹中对client.go,server.go,common.go这三个文件进行修改即可。注意事项(实

MarksSa的博客 832

课程1:认识Asp.net Core Web API

本文是《.Net Core从零学习搭建权限管理系统》教程专栏的导航站(点击链接,跳转到专栏主页,欢迎订阅,持续更新…)专栏介绍:以实战为线索,基于.Net 7 + REST + Vue、前后端分离,不依赖任何第三方框架,从零一步一步讲解权限管理系统搭建。专栏适用于人群:Web后端开发人员Web API是一个很广泛的概念,Asp.net Core Web API是.NET框架用于创建RESTful风格的项目、用于轻松构建可供多个客户端访问的HTTP服务。1、支持RestFul风格编程;

成长的足迹 1256

LeetCode腾讯精选练习50——第十二天

题目146:LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。 实现 LRUCache 类: LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。 void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它

qq_44315884的博客 205

六种光耦综合对比——《器件手册--光耦》

可控硅输出光耦(SCR Optocoupler)是一种特殊的光电耦合器,由红外发光二极管(LED)和双向可控硅(SCR)组成,用于实现输入和输出之间的电气隔离和信号传输。逻辑输出光耦是一种高效、可靠的数字信号隔离和电平转换器件,通过电气隔离和逻辑电平输出,确保了系统的安全性和信号的稳定性。固态继电器(可控硅输出,SSR)是一种无触点电子开关设备,利用可控硅(SCR或Triac)作为主要开关元件,通过光耦合器实现输入和输出之间的电气隔离。光耦作为一种成熟的电气隔离器件,在电子电路设计中具有重要的地位。

XU157303764的博客 1726

leetcode146、OrderedDict与lru_cache

本文探讨了Python中实现LRU缓存的两种方法:使用OrderedDict和哈希表+双向链表。首先介绍了leetcode146题LRU缓存的OrderedDict解法,该结构通过move_to_end和popitem方法自然契合LRU思想。然后分析了Python字典(dict)在3.6版本后实现的有序性特性,并指出其与OrderedDict的区别。最后深入研究了标准库functools.lru_cache的实现细节,展示了其采用哈希表+双向链表的方案,包括缓存命中和未命中时的处理逻辑、线程安全机制等核心实

usiel的博客 1023

Linux7 挂载 nfs 远程目录

每天一个 DBA 小知识,助你更进一步!

LuciferLiu_DBA 1万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

LeetCode 146. LRU 缓存机制(LRU Cache)

易错点正确做法说明更新数据未移动位置保证“最近使用”put 超过容量未淘汰使用删除头部get 不存在时返回错误返回-1使用是 Python 实现 LRU 的最简洁且效率最高的方式。同时掌握哈希表 + 双向链表手动实现 LRU 也是面试时加分项。本题考查的是缓存机制 + 数据结构的组合使用,属于高频面试题之一。错误点正确方式删除时未断开前后节点_remove()正确处理 prev/next忘记从cache删除淘汰节点双向链表头尾更新顺序错误始终更新 prev/next 的双向性。

2501_91641025的博客 1070

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

LeetCode 146. LRU Cache 题解

本题是 LRU 缓存的经典实现。双向链表维护使用顺序哈希表实现 O(1) 查找虚拟头尾节点简化操作移动节点到头部表示最近使用删除尾部节点表示逐出最久未使用。

cannonjinx的博客 2375

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

LRU Cache(最近最少使用)实现

LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。什么是Cache呢?狭义的Cache指的是位于CPU和主存间的快速RAM, 通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。广义上的Cache指的是位于速度相差较大的两种硬件之间, 用于协调两者数据传输速度差异的结构。

冰果滴的博客 1798

LRU Cache

LRU Cache

qq_67582098的博客 1318

Leetcode 146. LRU Cache

Leetcode 146. LRU Cache题目:解法1:ordered dictionary解法2:Hashmap+double linked list 题目: 解法1:ordered dictionary 用python内置的工具,关于这种解法不做详述,因为LRU这个题目肯定还是要要考察他的具体实现的,所以这种解法参考Leetcode官方即可: https://leetcode.com/problems/lru-cache/solution/ 解法2:Hashmap+double linked li

qq_37821701的博客 358

【LeetCode 热题 100】146. LRU 缓存——哈希表+双向链表

Problem:题目:请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。实现 LRUCache 类:LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1。void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value;

最短的捷径就是绕远路,绕远路才是我的最短捷径。 1257

LRU Cache(C++)

LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。什么是 Cache?狭义的Cache指的是位于CPU和主存间的快速RAM, 通常它不像系统主存那样使用 DRAM技术,而使用昂贵但较快速的SRAM技术。广义上的Cache指的是位于速度相差较大的两种硬件之间, 用于协调两者数据传输速度差异的结构。

sqm_C的博客 1067

其它高阶数据结构④_LRU_Cache(概念+实现OJ)

其它高阶数据结构④_LRU_Cache(概念+实现OJ)

参考书籍:《C语言程序设计》《数据结构》《C++ Primer》《Effective C++》《STL源码剖析》《现代操作系统》《UNIX环境高级编程》《图解TCP/IP》《图解HTTP》《Linux高性能服务器编程》《剑指Offer》《算法导论》 1124

[leetcode] 146. LRU Cache

感想 这道题在leetcode是hard的难度,通过率只有21.2%,我记得在某次笔试的时候做到了这一道题,那时候做得不怎么好,我这里把记录一下我以前写的代码,就当复习一下 题目 Design and implement a data structure forLeast Recently Used (LRU) cache. It should support the following ...

Learning from the mistakes 462

力扣经典题解:LRU缓存机制(146. LRU Cache)数据结构设计艺术

LRU 缓存设计完美展现了 ​数据结构组合​哈希表​:提供闪电般的键值查找能力​双向链表​:优雅维护访问时间序列​虚节点​:巧妙处理边界情况这种设计模式在系统开发中广泛应用,掌握它不仅提升算法能力,更能加深对实际系统设计的理解。算法如艺术,好的数据结构组合如同优美的建筑结构。LRU缓存设计的精妙之处在于其简单的结构达成了高效的操作,这正是计算机科学的魅力所在。

sheep404的博客 816

[LeetCode]146. LRU Cache 深入浅出讲解和代码示例

146. LRU Cache 解题思路涵盖了双向链表、哈希、缓存设计等知识点

karen0310的专栏 5995
上一篇: Leetcode NO.255 Implement Stack Using Queues 使用队列实现栈
下一篇: Leetcode NO.232 Implement Queue Using Stacks 使用栈实现队列
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值