什么是LFU算法?
- LFU算法淘汰的是使用频率最小的
- 它的名字是:Least Frequently Used algorithm
- 既然是跟频率有关的,那么就需要用数据结构来存放key-频率。
怎么写?
-
首先,列举基本的需求
- 在调用get(key)时,返回对应的value
- get 或 put 之后,这个key的频率 +1;
- 如果在容量满的时候进行put操作,那么就要删除频率最低的(通过频率找到key),如果有多个频率相同,删除最老的那个
- 以上操作希望是**O(1)**时间复杂度
-
根据要求,选择数据结构解决以上问题
- 用HashMap来存放key - value
- 用HashMap 来存放key-frequency,这样就可以通过key来快速找到它的频率
- 这一点是LFU算法的核心
- 需要一个frequency 到key的映射
- 需要一个变量minFreq来存放最小的频率
- 需要一个链表来存放一个freq对应的多个key
- freq对应的key列表是有时序的
- 希望能快速插入删除key列表中的元素
- 综上:frequency到key的映射使用HashMap<Integer, LinkedHashSet< Integer>>
-
编码:就是按照数据结构来填空几个函数
-
在increaseFreq函数中,怎么修改freqToKey表呢?
分三步
- 删除key项
- 如果freq+1不存在,创建
- 在freq+1的列表中,添加key
- 如果原来的freq列表因为本次操作,空了,那就删掉它
- 如果freq 是等于最小freq的,那么删除了freq列表后,最小freq需要++(因为freq+1 肯定存在)
-
deleteMinFreq函数要做什么?
-
处理fk表
-
获取到minFreq对应的列表
-
获取列表第一个元素key
-
在列表中把key删除
-
如果列表空了,删除这个列表(minFreq怎么更新?)
minFreq不用更新,因为删除这个minFreq之后肯定要插入一个新元素,到时候会处理minFreq
-
-
处理kf表
- 删除minFreq对应得元素
-
处理kv表
- 删除这个key
-
class LFUCache { int minFreq = 0; int cap; //容量 HashMap<Integer, Integer> keyToValue; HashMap<Integer, Integer> keyToFreq; HashMap<Integer, LinkedHashSet< Integer>> freqToKey; // 构造容量为 capacity 的LFU缓存 public LFUCache(int capacity)
-