算法通关村第五关-黄金挑战LRU问题

news2024/11/25 0:41:16

大家好我是苏麟 , 今天聊聊LRU问题 , 相信学过操作系统的小伙伴并不陌生 .

LRU问题

LRU的含义

LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。

图解 :

如果再有其他元素就依次类推。

LRU缓存

描述 :

设计和构建一个“最近最少使用”缓存,该缓存会删除最近最少使用的项目。缓存应该从键映射到值(允许你插入和检索特定键对应的值),并在初始化时指定最大容量。当缓存被填满时,它应该删除最近最少使用的项目。

它应该支持以下操作: 获取数据 get 和 写入数据 put 。

获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

题目 :

LeetCode LRU缓存 :

面试题 16.25. LRU 缓存

分析 :

目前公认最好的方式是使用Hash+双链表 :

Hash的作用是 用来做到O(1)访问元素,哈希表就是普通的哈希映射 (HashMap),通过缓存数据的键映射到其在双向链表中的位置。Hash里的数据是key-value结构。value就是我们自己封装的node , key则是键值,也就是在Hash的地址 .

这里的头节点 , 尾节点起到辅助的作用 , 并没有什么实际意义 , 相当于虚拟节点 . 

举例 :

我们先看容量为3的例子,首先缓存了1,此时结构如图a所示。之后再缓存2和3,结构如b所示。

之后 4再进入,此时容量已经不够了,只能将最远未使用的元素1删掉,然后将4插入到链表头部。此时就变成了上图c的样子。
接下来假如又访问了一次2,会怎么样呢? 此时会将2移动到链表的首部,也就是下图d的样子。

之后假如又要缓存5呢? 此时就将tail指向的3删除,然后将5插入到链表头部。也就是上图e的样子。上面的方案要实现是非常容易的 . 要注意链表的几个操作 :

.假如容量没满,则将新元素直接插入到链表头就行了

2.如果容量够了,新的元素到来,则将tail指向的表尾元素删除就行了

3.假如要访问已经存在的元素,则此时将该先从链表中删除,再插入到表头就行了

再看Hash的操作:
1.Hash没有容量的限制,凡是被访问的元素都会在Hash中有个标记,key就是我们的查询条件,而value就是链表的结点的引用,可以不用访问链表直接定位到某个结点,然后就可以执行我们在上一节提到的方法来删除对应的结点
2.这里双向链表的删除好理解,那HashMap中是如何删除的呢? 其实就是将node变成为null。这样get(key)的时候返回的是null,就实现了删除的功能
上述各项操作中,访问哈希表的时间复杂度为 O(1),在双向链表的头部添加节点、在双向链表的尾部删除节点的复杂度也为 O(1)。而将一个节点移到双向链表的头部,可以分成[删除该节点]和[在双向链表的头部添加节点]两步操作,都可以在 O(1)时间内完成

方法 : 

  • moveNode() 删除节点
  • removetail() 删除尾节点
  • addNode() 添加头节点
  • moveToHead() 移动到头节点
  • get() 得到节点的值
  • put() 插入节点

解析 :

class LRUCache {

    class Node{
        int key;
        int val;
        Node pre;
        Node next;

        public Node(){

        }
        public Node(int key , int val){
            this.key = key;
            this.val =val;
        }
    }

    private Map<Integer,Node> map = new HashMap<>();
    private Node head;
    private Node tail;
    private int size;
    private int capacity;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        head = new Node();
        tail = new Node();
        head.next = tail;
        tail.pre = head;
    }
    
    public int get(int key) {
        Node temp = map.get(key);
        if(temp == null){
            return -1;
        }
        moveToHead(temp);
        return temp.val;
    }
    
    public void put(int key, int value) {
        Node temp = map.get(key);
        if(temp == null){
            Node node = new Node(key,value);
            map.put(key,node);
            addNode(node);
            size++;
            if(size > capacity){
                Node delete = removetail();
                map.remove(delete.key);
                size--;
            }
        }else{
            temp.val = value;
            moveToHead(temp);
        }
    }
    
    //移动到头节点
    public void moveToHead(Node move){
        moveNode(move);
        addNode(move);
    }

    //添加头节点
    public void addNode(Node temp){
        temp.next = head.next;
        temp.pre = head;
        head.next.pre = temp;
        head.next = temp;
    }


    //删除尾节点并返回删除的节点
    public Node removetail(){
        Node temp = tail.pre;
        moveNode(temp);
        return temp;
    }

    //删除节点
    public void moveNode(Node temp){
        temp.pre.next = temp.next;
        temp.next.pre = temp.pre;
    }
}

/**
 * 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.coloradmin.cn/o/1170123.html

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

相关文章

ST表与RMQ(倍增表)

【概述】 RMQ : Range Maximum/minimum Query 这就是指区间最大或最小值&#xff08;区间最值&#xff09; ST表&#xff1a;Spars Table&#xff0c;一种可以解决 RMQ 的&#xff0c;基于倍增的数据结构&#xff0c;利用 ST 算法预处理打出的表&#xff0c;称为 ST 表。 …

EMC Unity存储系统如何查看SSD的使用寿命

为什么要写这个博客&#xff1f; 客户对老的EMC unity的存储系统要扩容&#xff0c;如何确定SSD磁盘是全新的还是拆机二手的&#xff1f;很多时候客户还有一个奇葩的要求&#xff0c;就是要和5年前的磁盘PN一致&#xff0c;甚至要求固件版本一致&#xff0c;最关键的还要求是全…

【LeetCode】每日一题 2023_11_4 数组中两个数的最大异或值

文章目录 刷题前唠嗑题目&#xff1a;数组中两个数的最大异或值题目描述代码与解题思路 结语 刷题前唠嗑 LeetCode? 启动&#xff01;&#xff01;&#xff01; 题目&#xff1a;数组中两个数的最大异或值 题目链接&#xff1a;421. 数组中两个数的最大异或值 题目描述 代…

分享去视频/图片水印的工具(完结篇)

简介 视频去水印是在数字时代日益重要和频繁的需求之一。水印是一种保护版权和确认身份的常见手段&#xff0c;但在某些情况下&#xff0c;水印可能会对视频内容产生负面影响&#xff0c;因此需要去除。 首先&#xff0c;视频去水印可以改善视频观看体验。有些视频平台或个人会…

非常有用的工具箱IT-Tools

什么是 IT-Tools &#xff1f; IT-Tools 汇集了 70 多种对开发人员和 IT 工作人员有用的工具。这个令人惊叹的工具的酷炫之处在于它不需要设置&#xff0c;不需要持久卷&#xff0c;您可以立即开始使用它。它包含大量工具&#xff0c;可生成密码、编辑 CSS 和 HTML 代码、文件格…

Blazor组件

Blazor组件 前言&#xff1a;博主文章仅用于学习、研究和交流目的&#xff0c;不足和错误之处在所难免&#xff0c;希望大家能够批评指出&#xff0c;博主核实后马上更改。 组件&#xff1a; Blazor 应用基于 Razor 组件&#xff0c;通常仅称为组件。 组件是 UI 的一个元素&…

自动驾驶算法(五):Informed RRT*算法讲解与代码实现(基于采样的路径规划) 与比较

目录 1 RRT*与Informed RRT* 2 Informed RRT*代码解析 3 完整代码 4 算法比较 1 RRT*与Informed RRT* 上篇博客我们介绍了RRT*算法&#xff1a;我们在找到一个路径以后我们还会反复的搜索。 Informed RRT*算法提出的动机(motivation)是能否增加渐近最优的速度呢&#xff1f;…

【腾讯云HAI域探秘】速通腾讯云HAI

速览HAI 产品简介 腾讯云高性能应用服务(Hyper Application lnventor&#xff0c;HA)&#xff0c;是一款面向 Al、科学计算的 GPU 应用服务产品&#xff0c;为开发者量身打造的澎湃算力平台。无需复杂配置&#xff0c;便可享受即开即用的GPU云服务体验。在 HA] 中&#xff0c;…

3000 台 Apache ActiveMQ 服务器易受 RCE 攻击

超过三千个暴露在互联网上的 Apache ActiveMQ 服务器容易受到最近披露的关键远程代码执行 (RCE) 漏洞的影响。 Apache ActiveMQ 是一个可扩展的开源消息代理&#xff0c;可促进客户端和服务器之间的通信&#xff0c;支持 Java 和各种跨语言客户端以及许多协议&#xff0c;包括…

Sentinel热点参数限流动

什么是热点 限流是统计访问某个资源的所有请求&#xff0c;判断是否超过QPS阈值。而热点参数限流是分别统计参数值相同的请求&#xff0c;判断是否超过QPS阈值。 何为热点&#xff1f;热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据&am…

关于Intel Press出版的《Bedyong BIOS》第2版的观后感

文章目录 此书的背景UEFI运行时DXE基础CPU架构协议PCI协议UEFI驱动的初始化串口DXE驱动示例 《Beyond BIOS》首先介绍一个简单的UEFI应用程序模块&#xff0c;用于展示UEFI应用程序的行为。作者为Waldo。该模块名为“InitializeHelloApplication”&#xff0c;它接受两个参数&a…

云栖大会,到底有些啥?

引言&#xff1a;10月31日至11月2日&#xff0c;2023云栖大会在杭州云栖小镇召开。小枣君去了现场&#xff0c;拍了一些照片&#xff0c;特来给大家做一个图文汇报。 云栖大会的前身&#xff0c;是2009年开始举办的地方网站峰会。2011年&#xff0c;这个峰会演变成阿里云开发者…

Linux的历史与环境

目录 Linux的背景介绍 Linux的时代背景-硅谷模式 计算机发展 UNIX发展历史 Linux诞生的偶然与必然 Linux开源 Linux发行版本 搭建Linux的环境 1.直接安装在物理机上 2.使用虚拟机软件 3.使用云服务器 &#xff08;1&#xff09;购买云服务器 &#xff08;2&#x…

docker是干什么的

很多朋友刚接触docker&#xff0c;不知道docker做什么&#xff0c; 这里白眉大叔给大家普及一下 docker的知识以及docker和虚拟机的区别。 你可以这样认为&#xff0c;docker 就是 打包应用程序的工具。 怎么理解这个工具呢&#xff1f; 1-如何理解docker 这个打包工具&#x…

作为一个初学者,该如何入门大模型?

在生成式 AI 盛行的当下&#xff0c;你是否被这种技术所折服&#xff0c;例如输入一段简简单单的文字&#xff0c;转眼之间&#xff0c;一幅精美的图片&#xff0c;又或者是文笔流畅的文字就展现在你的面前。 相信很多人有这种想法&#xff0c;认为生成式 AI 深不可测&#xf…

选择适合你的办公桌:提高工作效率的关键

​在如今的数字时代&#xff0c;越来越多的人将办公桌移到家里或办公室。但是&#xff0c;如何选择适合你的办公桌可能是个挑战。不同的工作需要和工作空间大小会影响你的选择。下面是一些简单的建议&#xff0c;帮助你找到适合你的办公桌&#xff0c;提高工作效率。 首先&…

世微 平均电流型降压恒流驱动器 电动摩托车LED灯小钢炮驱动IC AP5218

1&#xff0c;来源&#xff1a;深圳市世微半导体有限公司 2&#xff0c;产品描述 AP5218 是一款 PWM工作模式, 高效率、外 围简单、内置功率管&#xff0c;适用于5V&#xff5e;100V输入的高 精度降压 LED 恒流驱动芯片。输出最大功率可达 15W&#xff0c;最大电流 1.5A。AP5…

Leetcode—2512.奖励最顶尖的K名学生【中等】

2023每日刷题&#xff08;十九&#xff09; Leetcode—2512.奖励最顶尖的K名学生 哈希表stringstream排序算法思想 实现代码 class Solution { public:vector<int> topStudents(vector<string>& positive_feedback, vector<string>& negative_feed…

MySQL中如何书写update避免锁表

1. 什么是MySQL锁表&#xff1f; MySQL锁表是指在对某个数据表进行读写操作时&#xff0c;为了保证数据的一致性和完整性&#xff0c;系统会对该数据表进行锁定&#xff0c;防止其他用户对该表进行操作。 2. 为什么会出现锁表&#xff1f; 当多个用户同时对同一个数据表进行…

(附源码)基于springboot校园自媒体信息服务平台-计算机毕设 84565

springboot校园自媒体信息服务平台 目 录 摘要 1 绪论 1.1课题意义 1.2开发现状 1.3系统开发技术的特色 1.4springboot框架介绍 1.5论文结构与章节安排 2 2校园自媒体信息服务平台系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1数据增加流程 2.3.2数据修改流程 2…