力扣146|LRU缓存淘汰算法

news2024/11/24 11:53:19

LRU缓存淘汰算法

leet code146: https://leetcode.cn/problems/lru-cache

一、基本思想

1.1 基本思想

LRU全名Last Recently Used,即当缓存空间满时,优先淘汰最不常使用(访问)的缓存。

1.2 抽象接口

1、 init() 初始化大小为N的缓存空间

2、 put(key, val) 将id为key的缓存加入缓存空间,要求O(1)时间复杂度

3、get(key) 得到id为key的缓存,要求O(1)时间复杂度

明确行为:

要实现缓存访问时间的区别,所选的数据结构最好能保持元素有序。

在put存一个缓存时,有可能是插入,也有可能是更新。不论是插入还是更新,id为key的缓存页都被访问了一次,需要将它的优先级提高。插入时还需要考虑缓存满,需要选择一个缓存页淘汰。

在get一个缓存时,访问了一遍id为key的缓存,需要提高它的优先级。

二、代码实现

2.1 数据结构

插入删除要求O(1),自然是选择链表。

查找更新要求O(1),肯定是哈希表。

两者结合就形成了哈希链表,LinkedHashMap。

在这里插入图片描述

2.2 借助API实现

class LRUCache {
    int cap;
    // 插入队尾,就是最常使用的
    LinkedHashMap<Integer, Integer> cache = new LinkedHashMap<>();
    public LRUCache(int capacity) {
        cap = capacity;
    }
    
    public int get(int key) {
        int val = -1;
        if(cache.containsKey(key)){
            // 得到值
            val = cache.get(key);
            // 提升这个值到队尾
            cache.remove(key);
            cache.put(key, val);
        }
        return val;
    }
    
    public void put(int key, int val) {
        if(cache.containsKey(key)){
            cache.put(key, val); //变更数据
            this.get(key);
            return;
        }else{
            // 插入需要先判断容量是否已满
            if(cache.size()>=this.cap){
                // 淘汰队首
                int oldKey = cache.keySet().iterator().next();
                cache.remove(oldKey);
            }
                cache.put(key, val);
            }
        }
    }
}

我们用链表存数据,最新的数据插入到队尾。

get要做的事情:得到key对应的值,将key优先级提高。

put要做的事情:判断key在不在链表中,相应的修改/插入操作行为。

​ 修改操作:修改值,提升优先级。

​ 插入操作:判断队伍空间是否满,已满需要淘汰队首。然后在插入。

2.3 自己实现哈希链表

(1)想明白

要做哪些事?

  • 自己实现双向链表
  • 利用HashMap哈希表
  • 整合这两个为哈希链表

哈希链表要实现哪些API?

  • get 根据key得到值
  • put 根据key进行修改或插入操作
  • remove 删除指定key

双向链表要实现的API:

  • 插入节点
  • 删除节点(给出Node)

(2)双向链表实现

class Node{
    public int key,val;
    public Node prev,next;
    Node(int key, int val){
        this.key = key;
        this.val = val;
        prev = null;
        next = null;
    }
}

class DoubleList{
    private Node dummyNode;
    public int size;
    DoubleList(){
        dummyNode = new Node(-1, -1);
        dummyNode.prev = dummyNode;
        dummyNode.next = dummyNode;
        size = 0;
    }
    public void insert(Node tmp){
       tmp.prev = dummyNode.prev;
       tmp.next = dummyNode;
       dummyNode.prev.next = tmp;
       dummyNode.prev = tmp;
       size+=1;
    }
    public void remove(Node tmp){
       if(size<=0) return;
       Node front  = tmp.prev;
       Node rear = tmp.next;
       front.next = rear;
       rear.prev = front;
       tmp.prev = null;
       tmp.next = null;
       size-=1;
    }
    public int removeFirst(){
        int ret = dummyNode.next.key;
        remove(dummyNode.next);
        return ret;
    }
}

技巧:

  • 伪头节点
  • 循环链表

(3) LRUCache实现

class LRUCache {
    private HashMap<Integer, Node> map;
    private DoubleList cache;
    private int cap;
    public LRUCache(int capacity) {
        cap = capacity;
        map = new HashMap<>();
        cache = new DoubleList();
    }
    
    public int get(int key) {
        Node tmp = map.get(key);
        int val = -1;
        if(tmp==null) return val;
        val = tmp.val;
        cache.remove(tmp);
        cache.insert(tmp);
        return val;
    }
    
    public void put(int key, int val) {
        Node tmp = map.get(key);
        if(tmp==null){
            // 插入操作,判断队满
            if(cache.size == cap){
               int oldkey = cache.removeFirst();
               map.remove(oldkey);
            }
            Node new_tmp = new Node(key,val); 
            map.put(key, new_tmp);
            cache.insert(new_tmp);
        }else{
            // 更新操作
            cache.remove(tmp);
            tmp.val = val;
            cache.insert(tmp);
        }
    }
}

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

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

相关文章

ITSM和ITIL有什么区别?

ITIL是最广泛接受的ITSM方法&#xff0c;是用于管理组织IT运营和服务的最佳实践和建议的框架。它是由英国政府的中央计算机和电信局&#xff08;CCTA&#xff09;在1980年代中期委托创建的。基于ITIL框架构建的ITSM流程为更好的IT服务和改善业务铺平了道路。总而言之&#xff0…

【Java】关于我Debug的一些技巧

文章目录 条件断点断点回退表达式的执行直接返回 条件断点 IDEA中右击断点的时候可以看到如下的状态&#xff0c;在这里的Condition中我们可以选择进入当前断点的一个条件&#xff0c;比如我希望只有keyuser2的时候才进入断点&#xff0c;那么我就可以按照如下的方式去编写条件…

前端架构师之01_JQuery

1 jQuery快速入门 1.1 什么是jQuery 它是一个开源的JavaScript类库 。 常见的JavaScript类库&#xff1a;jQuery、Prototype、ExtJS、Mootools和YUI等。 jQuery的核心理念&#xff1a;write less&#xff0c;do more&#xff08;写的更少&#xff0c;做的更多&#xff09;。…

五、回溯(trackback)

文章目录 一、算法定义二、经典例题&#xff08;一&#xff09;排列1.[46.全排列](https://leetcode.cn/problems/permutations/description/)&#xff08;1&#xff09;思路&#xff08;2&#xff09;代码&#xff08;3&#xff09;复杂度分析 2.[LCR 083. 全排列](https://le…

优优嗨聚集团:美团代运营服务,对美团外卖商家有何促进

美团代运营服务一直是美团外卖商家成功的关键因素之一。美团代运营服务是一种专业的营销服务&#xff0c;它可以帮助商家在美团平台上更好地经营和销售&#xff0c;从而提高店铺曝光率、提升用户评价、提高营收等方面的水平。 首先&#xff0c;美团代运营服务可以帮助商家提高店…

4.canvas绘制基本图形——折线

在日常生活中&#xff0c;除了矩形与圆弧外&#xff0c;接触最多的就是折线了。甚至矩形也可以看出是一段折线&#xff0c;所以我们自然也可以使用绘制折线的方式绘制出矩形 moveTo 认识折线之前&#xff0c;我们先认识下moveTo这个方法。形象一点说这个方法就是将我们的画笔…

Leetcode 1239. 串联字符串的最大长度

文章目录 题目代码&#xff08;9.29 首刷部分看解析&#xff09; 题目 Leetcode 1239. 串联字符串的最大长度 代码&#xff08;9.29 首刷部分看解析&#xff09; class Solution { public:unordered_set<int> skip;unordered_set<char> used;int maxLength(vecto…

常见的7种分布式解决方案(2pc,3pc,Tcc,Seta、本地事务....)

一 分布式事务 1.1 分布式事务 在分布式系统中一次操作需要由多个服务协同完成&#xff0c;这种由不同的服务之间通过网络协同完成的事务称为分布式事务。 1.首先满足事务特性&#xff1a;ACID 2.而在分布式环境下&#xff0c;会涉及到多个数据库 总结&#xff1a;分布式事务…

搭建自己的搜索引擎之三

一、前言 接上一篇 搭建自己的搜索引擎之二&#xff0c;本篇主要讲一下我们如何操作ElasticSearch&#xff0c;就是最简单的增删改查命令怎么写。 二、几个概念 搭建自己的搜索引擎之一 这篇文章我们对比搜索引擎在做海量数据实时查询优于关系型数据库的一些原因&#xff0c…

山西电力市场日前价格预测【2023-09-29】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-09-29&#xff09;山西电力市场全天平均日前电价为189.30元/MWh。其中&#xff0c;最高日前电价为338.58元/MWh&#xff0c;预计出现在18: 45。最低日前电价为0.00元/MWh&#xff0c;预计出…

V4L2 驱动架构介绍

V4L2 简介 Video for Linux two(Video4Linux2)简称 V4L2&#xff0c;是 V4L 的改进版。V4L2 是 linux操作系统下用于视频和音频数据采集设备的驱动框架&#xff0c;为驱动和应用程序提供了一套统一的接口规范。 在 Linux 下&#xff0c;所有外设都被看成一种特殊的文件&#xf…

重大发布 | 雷特百元级DALI主控 200场景·万灯独控·有线无线全覆盖

中秋国庆放假安排 喜迎国庆、欢度中秋。按照国家有关规定&#xff0c;智哪儿定于9.29-10.6期间放假&#xff0c;10.7-10.8正常上班。 假期期间&#xff0c;智哪儿全平台暂停更新。祝大家合理安排好假期生活&#xff0c;度过一个愉快的假期。

力扣 -- 115. 不同的子序列

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:int numDistinct(string s, string t) {int ns.size();int mt.size();//多开一行&#xff0c;多开一列vector<vector<double>> dp(m1,vector<double>(n1));for(size_t j0;j<n;j){dp[…

嵌入式开源库之libmodbus学习笔记

socat 安装sudo apt-get install socat创建终端 socat -d -d pty,b115200 pty,b115200查看终端 ls /dev/pts/ minicom 安装 sudo apt-get install minicom链接虚拟终端 sudo minicom -D /dev/pts/3以十六进制显示 minicom -D /dev/pts/1 -H设置波特率 minicom -D /dev/pts/1…

【神经网络可视化】 梯度上升,可视化工具,风格转移

可视化可以帮助我们更好的理解卷积网络每一层学到了什么&#xff0c;或者说每一个卷积核究竟学到了什么&#xff0c;他是怎么理解图像的 这种的话当我们神经网络结果不太好时&#xff0c;我们可以分析不好的原因 图片来源于李飞飞老师的内容 梯度上升方法做可视化 文章目录 …

Spring整合第三方框架-MyBatis整合Spring实现

Spring整合MyBatis的步骤 导入MyBatis整合Spring相关坐标。 <dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.5</version></dependency><dependency><groupId>…

Docker下如何构建包含延迟插件的RabbitMQ镜像

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

低温结霜可视化实验装置的真空压力精密控制技改方案

摘要&#xff1a;低温结霜可视化实验装置主要用于模拟空间环境并研究深冷表面结霜现象&#xff0c;客户希望对现有实验装置的真空系统进行技术升级&#xff0c;以实现0.001Pa~1000Pa范围内真空度的准确控制。为此本文提出了分段控制解决方案&#xff0c;即采用电容真空计、电动…

04. 人工智能核心基础 - 导论(3)

文章目录 人工智能和其他学科的关系为什么学习人工智能怎么学好人工智能&#xff1f;一些问题 Hi&#xff0c;你好。我是茶桁。 基于上一节课咱们的整体强度有点大&#xff0c;而且咱们马上也要进入高强度内容了&#xff0c;那么这一篇咱们就稍微水一篇吧。来聊聊天&#xff0…

publicPath:打包时的配置

vue项目&#xff0c;执行打包命令后&#xff0c;会在项目的根目录中自动创建一个文件夹dist,dist中的文件就是打包后的文件&#xff0c;只需要放到服务器中即可。 【默认情况下&#xff0c;用的绝对路径&#xff0c;需要放到服务器的根目录打开。】 如果希望放到子目录也能运行…