LeetCode146-LRU缓存机制_腌制99%的咸鱼的博客-程序员宅基地

技术标签: java  链表  leetcode  缓存  

LeetCode146-LRU缓存机制

题目

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。

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

LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 该操作会使得关键字 2 作废
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 该操作会使得关键字 1 作废
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4

解法

方法一:自己实现一个Map和双向链表的方法

class LRUCache {
    
    Map<Integer,DoubleNode> map = new HashMap<>();
        int n ;
        int len;
        DoubleNode dummy = new DoubleNode(0,0);
        DoubleNode tail = dummy;
        public LRUCache(int capacity) {
    
            n = capacity;
        }

        public int get(int key) {
    
            if(!map.containsKey(key)) return -1;
            DoubleNode res = map.get(key);
            if(res.next!=null){
    
                res.pre.next = res.next;
                res.next.pre = res.pre;
                tail.next = res;
                res.pre = tail;
                tail = res;
                tail.next = null;
            }
            return res.val;
        }

        public void put(int key, int value) {
    
            if(map.containsKey(key)){
    
                get(key);
                tail.val = value;
            }else{
    
                DoubleNode cur = new DoubleNode(key,value);
                if(len == n ){
    
                    DoubleNode temp = dummy.next;
                    map.remove(temp.key);
                    if(n==1){
    
                        dummy.next = null;
                        tail = dummy;
                    }
                    else{
    
                    	//这里要注意不要写错了
                        DoubleNode c = dummy.next.next;
                        dummy.next = c;
                        c.pre = dummy;
                    }
                }else{
    
                    ++len;
                }
                map.put(key,cur);
                tail.next = cur;
                cur.pre = tail;
                tail = tail.next;
            }

        }
		//双向链表
        class DoubleNode{
    
            int key;
            int val;
            DoubleNode next;
            DoubleNode pre;
            public DoubleNode(){
    }
            public DoubleNode(int x,int y){
    
                key = x;
                val = y;
            }
        }
}

方法二:

class LRUCache extends LinkedHashMap<Integer, Integer>{
    
    private int capacity;
    
    public LRUCache(int capacity) {
    
        super(capacity, 0.75F, true);
        this.capacity = capacity;
    }

    public int get(int key) {
    
        return super.getOrDefault(key, -1);
    }

    public void put(int key, int value) {
    
        super.put(key, value);
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
    
        return size() > capacity; 
    }
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/viva_la__vida/article/details/108888151

智能推荐

mac webstorm 使用typescript 和配置自动编辑_拉不拉丁的博客-程序员宅基地

Name:TypeScriptFile Type:TypeScriptScope:All PlacesProgram:/usr/local/lib/node_modules/typescript/bin/tsc(既安装typescript的路径下的tyc文件)Arguments:--sourcemap --target "ES5"Output paths to refresh:$FileNameWithoutExtension$.js:$FileNameWithoutExtension$.js.m

Django DateField DateTimeField TimeField_django语句中datatimefield如何设置_公众号: DCOS的博客-程序员宅基地

首先说下没营养但需要了解的前三个modelField,DateTimeField和DateField和TimeField存储的内容分别对应着datetime(),date(),time()三个对象。    对于auto_now=False和auto_now_add=False。由于开始不太清楚这两个属性的作用,于是费了不少时间才查到这里的问题。两者默认值都为False。    auto_n

渗透测试常用工具-stunnel内网穿透__abcdef的博客-程序员宅基地

关于内网穿透原理可以查看我另外一篇文章介绍:渗透测试常用工具-ptunnel内网穿透Stunnel是一个自由的跨平台软件,用于提供全局的TLS/SSL服务。针对本身无法进行TLS或SSL通信的客户端及服务器,Stunnel可提供安全的加密连接。该软件可在许多操作系统下运行,包括Unix-like系统,以及Windows。Stunnel依赖于某个独立的库,如OpenSSL或者SSLeay,以实现T...

Mybatis Plugin插件安装破解及使用_weixin_34357436的博客-程序员宅基地

为什么80%的码农都做不了架构师?&gt;&gt;&gt; ...

bayer格式插值算法实现_bayer插值算法_奥比中光3D视觉开发者社区的博客-程序员宅基地

bayer格式插值红蓝算法实现每一个像素仅仅包括了光谱的一部分,必须通过插值来实现每个像素的RGB值。为了从Bayer格式得到每个像素的RGB格式,我们需要通过插值填补缺失的2个色彩。插值的方法有很多(包括领域、线性、3*3等),速度与质量权衡,最好的线性插值补偿算法。其中算法如下:R和B通过线性领域插值,但这有四种不同的分布,如下图所示:在(a)与(b)中,R和B分别取邻域的平均值。在(c)与(d)中,取领域的4个B或R的均值作为中间像素的B值。bayer格式插值绿算法实现由于人眼对绿光反

Vue登录密码的显示与隐藏_vuetify 登录_莫亓的博客-程序员宅基地

点击小眼睛图标,实现输入框中密码的显示与隐藏: &lt;i class="icon-password"&gt;&lt;/i&gt; &lt;input type="text" v-if="pwdType" v-model="eyeTxt" /&gt; &lt;input type="password" placeholder="输入新密码" v-model="eyeTxt" v-...

随便推点

intellij idea 安装激活破解方法_thiscracklicenseid_sleepwalker_1992的博客-程序员宅基地

1、intellij idea下载安装https://www.jetbrains.com/idea/2、打开http://idea.lanyus.com/下载破解补丁3、将补丁复制到intellij idea安装目录的bin目录下D:/Program Files/JetBrains/IntelliJ IDEA 2018.3/bin4、修改该bin目录下的 idea.exe...

数字IC设计学习笔记_8位7段数码管1_8位七段式数码管_GloriaHuo的博客-程序员宅基地

数字IC设计学习笔记8位7段数码管1 原理图2 Verilog 代码3 Modelsim仿真1. 原理图8位数码管数码管内部结构图数码管分为共阴极数码管和共阳极数码管;本文采用共阳极数码管。每个数码管内部的led灯的所有阳极连在一起,给正电压;当三极管的基极为高电平,三极管导通,VCC通过电阻,三极管加载到led灯的阳极。当led灯阴极为低电平,led灯点亮;当led灯阴极为高电平,led灯灭。由于无法同时点亮8个数码管中单一的一个led灯,故采用动态扫描实现。动态扫描:将操作平均

html form表单密码隐藏,基于vue 实现表单中password输入的显示与隐藏功能_芙蓉塘外有轻雷的博客-程序员宅基地

实现效果:点击 “眼睛” 的时候显示与隐藏代码:Title#main{text-align: center;margin-top:60px;}input[type=text],input[type=password]{width:260px;height:28px;display: inline-block;}span{margin-left:-30px;cursor: pointer;}inpu...

C语言结构体大小计算举例(二)_c怎么读取结构体的长度_Dr.CB的博客-程序员宅基地

这篇文章来探讨一下C语言中,结构体占的内存大小如何计算。printf(“str = %d”, sizeof(struct str));//用这个方法来查看一个结构体的大小 我尝试了好几次发现一个奇怪的现象,当定义一个结构体变量的时候,结构体成员的顺序不同就会造成这个结构体所占的空间大小的不同。这是什么原因呢?原来是因为在编译器中,为了CPU访问数据的高效率。如果变量的地址不对齐,那么CPU读取结构体就需要对结构体成员进行重复的访问,然后组合得到整型数据。而如果变量在自然对齐位置上,则只要一次就可以取

关于mysql数据库在输入密码后,滴的一声直接退出界面的解决办法(详细办法)_mysqli密码错了函数直接停止_追寻灯火阑珊的博客-程序员宅基地

前一阵子,由于写程序要用到数据库,便在本子上下载了一个,却出现很多小问题(自己的台式机却没有该问题,可能是本人的本子太渣了吧),纠结了好一阵,回头想想,发现问题,分析问题,解决问题,不就是我们的软件管理的思想嘛,只有经历过问题,才能深刻理解。废话不多说了,直接上题。下载好mysql后,当你打开mysql的字符界面时(MySQL 5.5 Command Line Client),输入密码(在安装

推荐文章

热门文章

相关标签