labuladong公众号算法学习笔记
LRU算法 相当于把数据按照时间排序,这个需要借助链表很自然就能实现,如果一直从链表头部加入元素,越靠近头部的元素就是新数据,越靠近尾部就是旧数据,只要简单把尾部元素淘汰掉即可。
LFU算法 相当于是淘汰访问频次最低的数据。如果访问频次最低的数据有多条,需要淘汰最旧的数据。把数据按照访问频次进行排序,频次还会不断变化。
算法描述
class LFUCache{
//构造容量为capacity的缓存
public LFUCache(int capacity){
}
//在缓存中查询key
public int get(int key){
}
//将key和val存入缓存
public void put(int key,int val){
}
}
- get(key)在缓存中查询键key,存在返回val;不存在返回-1
- put(key,val)插入或修改。若存在key,则修改;不存在则插入。
- 当缓存达到capacity时,在插入之前,删除使用频次(freq)最低的键值对。如果freq有多个,则删除其中最旧的那个。
思路分析
1、使用一个HashMap存储key到val的映射,快速计算get(key)
HashMap<Integer,Integer> keyToVal;
2、使用一个HashMap存储key到freq的映射,快速操作key对应的freq
HashMap<Integer,Integer> keyToFreq;
3、算法核心:
3.1、需要freq到key的映射,来找到freq最小的key。
3.2、用minFreq来记录当前最小的freq
3.3、freq对key是一对多的关系,即一个freq对应一个key列表
3.4、freq对应的key的列表是存在时序的
3.5、需要快速删除key列表中任何一个key。因为如果频次为freq的某个key被访问,那么它的频次就变为了freq+1,就应该从freq对应的key列表中删除,加到freq+1对应的key列表中。
HashMap<Integer,LinkedHashSet<Integer>> freqToKeys;
int minFreq=0;
LinkedHashSet,链表和哈希集合的结合体。链表插入元素有时序性,哈希集合可以对元素进行快速访问和删除。
LFU基本数据结构:
class LFUCache{
//key到val的映射,称为KV表
HashMap<Integer,Integer&g