开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 30 天,点击查看活动详情
在做题时候遇到这样一个问题,看完题目描述时候感觉有思路又好像一脸懵逼,下面我们一起看一下这个题
什么是LRU
LRU是一种内存淘汰策略,他的特点是最近最少使用的被替换。比如下图(假设我们内存占3个空间,输入队列为70120304,那么替换图如下)
当2(第四个数)进入时候,内层里面已经满了,需要进行替换,按照最近最少使用来看,7是最远使用的,使用7出内存。又因为最近原则,所以2是此时最近使用的。内存序列:210。当0(第5个数)进入时候,内存已经满了,且内存里面有0,使用直接修改0是最近最少使用的。变成021.后面都是类似的
由此看来,题目里面Solution(int capacity)就算初始化内存空间几个。set是加入内存,get是检查有没有数。
分析
如果我们使用数组进行设置的话,因为存在大量拷贝操作,所以性能方面可能无法满足我们的需要,我们需要的是加入和删除都是时间复杂度O(1)的操作,并且需要把访问次序维护好,并且这个次序维护并不是单纯排序那么我们可以选择双向链表。
那么我们统一知道,双向链表不能随机访问,或者说查询时间复杂度很大。那么有没有一种结果可以查询快,加入删除也快?我想了想,单纯某结构好像不太可能。
这个时候,我想起来之前排序的算法,快排也是,当数据量少用xx方法,数据量大用xx方法。所以 基于 HashMap + 双向链表 实现我们想要的时间复杂度。
思路有了,那么我们如何进行算法设计?
代码实现
- 第一步:设置一个双向链表
-
第二步:设置全局变量标识链表头尾和剩余大小
-
第三步,变量操作数组,判断是set还是get
-
set:需要把key值和value值加入链表,先检查链表里面有没有key,通过hash表检查,如果有,就直接通过hash访问节点,修改value,并且把访问过的放在表头。如果hash里面没有值,就需要新建节点加入到表,并且检查表是不是超出长度了,是就把表尾去掉。
-
删除值,需要断掉和前面原神的连接,同时在hash表里面去掉key
-
get:检查hash表里面有没有数,如果没有返回-1,有就进行访问