632次浏览 发布时间:2024-03-11 07:17:19
理解LRU
设计一个LRU,你得知道什么是LRU吧?
LRU,英文全称为Least Recently Used,翻译过来就是最近最久未使用算法,是一种常用的页面置换算法。
说起页面置换算法,这就是跟OS关系比较大的了,我们都知道内存的速度比较快,但是内存的容量是非常有限的,不可能给所有页面装到内存中,所以就需要一个策略将常用的页面预放到内存中。
但是吧,谁也不知道进程下次会访问哪个内存,并不能很有效的知道(我们在当前并没有预测未来的功能),所以有些页面置换算法只是理想化但是没法真实实现的(没错就是最佳置换算法(Optimal)),然后常见必回的算法就是FIFO(先进先出)和LRU(最近最久未使用)。
LRU理解不难,就是维护一个有固定大小的容器,核心就是get()和put()两个操作。
我们先看一下LRU会有的两个操作:初始化:LRUCache(int capacity) ,以正整数作为容量 capacity 初始化 LRU 缓存。
查询:get(int key),从自己的设计的数据结构中查找是否有当前key对应的value,如果有那么返回对应值并且要将key更新记录为最近使用,如果没有返回-1。
插入/更新:put(int key,int value),可能是插入一个key-value,也可能是更新一个key-value,如果容器中已经存才这个key-value那么只需要更新对应value值,并且标记成最新。如果容器不存在这个值,那么要考虑容器是否满了,如果满了要先删除最久未使用的那对key-value。
这里的流程可以给大家举个例子
这个过程如下:
大家容易忽略的细节有:
对于上面的这么一个规则,我们该如何处理呢?
如果单单用一个List类似的列表,可以顺序存储键值对,在List前面的(0下标为前)我们认为它是比较久的,在List后我们认为它是比较新的。我们考虑下各种操作可能会这样设计:
如果来get操作:
遍历List一个个比对,查看是否有该key的键值对,如果有直接返回对应key的value,如果没有那么返回-1.
如果来put操作:
遍历List,如果有该key的键值对,那么果断删除这个key-value,最后在末尾统一插入该键值对。
如果没有对应的key并且List容器已经到达最满了,那么果断删除第一个位置的key-value。
用List可能需要两个(一个存key一个存value),或者一个存Node节点(key,value为属性)的List,考虑下这个时间复杂度:
put操作:O(n),get操作:O(n) 两个操作都需要枚举列表线性复杂度,效率属实有点拉胯,肯定不行,这样的代码我就不写了。
从上面的分析来看,我们已经可以很自信的将LRU写出来了,不过现在要考虑的是一个优化的事情。
如果说我们将程序中引入哈希表,那么肯定会有一些优化的。用哈希表存储key-value,查询是否存在的操作都能优化为O(1),但是删除或者插入或者更新位置的复杂度可能还是O(n),我们一起分析一下:
最久未使用一定是一个有序的序列来储存,要么是顺序表(数组)要么是链表,如果是数组实现的ArrayList存储最久未使用这个序列。
如果是ArrayList进行删除最久未使用(第一个)key-value,新的key被命中变成最新被使用(先删除然后插入末尾)操作都是O(n)。
同理如果是LinkedList的一些操作大部分也是O(n)的,像删除第一个元素这个是因为数据结构原因O(1)。
你发现自己的优化空间其实非常非常小,但是确实还是有进步的,只是被卡住不知道双O(1)的操作究竟怎么优化,这里面我把这个版本代码放出来,大家可以参考一下(如果面试问到实在不会可以这么写)
上面我们已经知道用哈希能够直接查到有木有这个元素,但是苦于删除!用List都很费力。
更详细的说,是苦于List的删除操作,Map的删除插入还是很高效的。
在上面这种情况,我们希望的就是能够快速删除List中任意一个元素,并且效率很高,如果借助哈希只能最多定位到,但是无法删除啊!该怎么办呢?
哈希+双链表啊!
我们将key-val的数据存到一个Node类中,然后每个Node知道左右节点,在插入链表的时候直接存入Map中,这样Map在查询的时候可以直接返回该节点,双链表知道左右节点可以直接将该节点在双链表中删除。
当然,为了效率,这里实现的双链表带头结点(头指针指向一个空节点防止删除等异常情况)和尾指针。
对于这个情况,你需要能够手写链表和双链表啦,双链表的增删改查已经写过清清楚楚,小伙伴们不要担心,这里我已经整理好啦
也就是你可以通过HashMap直接得到在双链表中对应的Node,然后根据前后节点关系删除,期间要考虑的一些null、尾指针删除等等特殊情况即可。
具体实现的代码为:
就这样,一个get和put都是O(1)复杂度的LRU写出来啦!
目前最火的仙侠手游推荐,最好玩的仙侠手游排行榜
2025-09-10 22:29:26DNF黄金周用黄金胶囊,版本养猪超轻松
2025-09-04 08:12:59从无人问津到万众期待?回顾《骑马与砍杀》系列游戏的发展轨迹
2025-09-04 03:18:31怪兽8号手游好玩吗?值得玩吗?真实体验告诉你答案
2025-09-03 13:32:30EA免费游戏《极速滑板》9月16日登陆抢先体验
2025-09-03 02:59:05姬小满如此强大,KPL关键对局却选亚连,两个英雄有啥区别呢
2025-09-02 10:16:26《英雄年代》手游:特色活动大揭秘,欢乐无限笑江湖
2025-09-02 03:53:01《失踪的班班 Missing Banban》横版动作冒险里Banban宇宙疯狂友情
2025-09-01 21:16:45Switch NSP中文 浪漫沙迦开拓者 2 复刻版/SaGa 未拓領域 2 Remastered
2025-09-01 12:31:09兵团突击:现代战争Operation: Polygon Storm Switch NSP中文
2025-08-31 23:38:54女生怎样让男生更离不开你(让男人,离不开你的方法)
发布时间:2025-08-13 02:12:17对异性说晚安的含义是什么(你知道晚安的真正含义吗)
发布时间:2025-08-12 09:01:29难以维持的婚姻要怎么办(夫妻间一定要做这些事情)
发布时间:2025-08-12 02:24:16女朋友说不合适要怎么挽回(对方觉得不合适分手,应该如何挽回?)
发布时间:2025-08-11 09:22:49直男喜欢什么类型的女孩子(直男眼中的“女神”有三种类型)
发布时间:2025-08-11 02:25:16男女之间在玩暧昧的表现(有过以下三种“亲密举动”,往往关系就暧昧了)
发布时间:2025-08-10 12:21:56网站内容来自网络,如有侵权请联系我们,立即删除!
Copyright © 鸾百科 琼ICP备2023010660号-6