LRU算法就是计算机的缓存满了要删除一些内容给新内容腾出位置的缓存淘汰算法。LRU 的全称是 Least Recently Used,认为最近使用过的数据是有用的,内存满了,就删除哪些很久没有用过的数据。比如我的手机只能开3个应用,再开一个应用会取代最久未使用的应用程序。
1.LRU算法
leetcode146题
要求:请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
解决思路:数据结构满足条件
1.有时序来区分最近使用和久未使用;
2.查找某个键对应的O(1) 的平均时间复杂度。
3.每次访问要变为最近使用,支持任意位置快速插入和删除。 O(1) 的平均时间复杂。
什么数据结构符合上述条件呢?哈希表查找快,但数据无固定时序。链表有顺序之分,插入和删除快,但查找慢。所以我们取两者长,形成一种新的数据结构:哈希链表LinkedHashMap。
数据结构如下
哈希表中存储了键,值为链表结点,查找某个结点快。
```Java
public class LRU {
int cap;//最大容量
LinkedHashMap<Integer,Integer> cache=new LinkedHashMap<>();//哈希链表
public LRU(int cap){
this.cap =cap;
}
public int get(int key){
if(!cache.containsKey(key)){
return -1;
}
//将key变为最近使用
makeRecently(key);
return cache.get(key);
}
public void put(int key,int val){
if(cache.containsKey(key)){
cache.put(key,val);
makeRecently(key);
return;
}
if(cache.size()>=this.cap){
//链表的头部就是最久未使用的key
int oldestKey=cache.keySet().iterator().next();
cache.remove(oldestKey);
}
cache.put(key,val);
}
private void makeRecently(int key) {
int val=cache.get(key);
//删除key,重新插入到队尾
cache.remove(key);
cache.put(key,val);
}
}
```
Java中的哈希链表,操作方法:remove,put,get。与hashmap类似。
2.LFU算法
leetcode460题
LFU也是一个著名的缓存淘汰算法。⽽ LFU 算法的淘汰策略是 Least Frequently Used,也就是每次淘汰那些使⽤次数最少的数据。
时间复杂度O(1)。
LRU算法是把数据按照时间排序,这个需求借助链表就可以实现。LFU算法相当于把数据按照访问频次进行排序,访问次数相同就删除最早的数据。
解题思路:
1.调用get(key)方法时,要返回该key对应的val。
2.只要用get或者put方法访问一次某个key,该key的freq就要加一。
3.如果在容量满了的时候进行插入,则要频率最小的删除,如果多个key删除其中最久的那一个。
我们需要维护三个数据结构
1.key-value对:通过key能够找到该key对应的值,用hashMap就可以实现。
2.key-freq对:只要访问一次key,对应的频率加1,也可以用hashMap实现。
3.freq-keys对:同一个频率可能会对应多个键,就应该删除最早的数据,用LinkedHashMap实现保证有序。
注意:我们可以用一个参数来记录当前频率最小的值。
LRU算法是一种缓存淘汰策略,当内存满时,它会删除最近最少使用的数据。文章介绍了LRU的实现思路,包括使用哈希链表LinkedHashMap,并对比了LFU算法,后者基于访问频次淘汰数据,同样保证O(1)的时间复杂度。

6644

被折叠的 条评论
为什么被折叠?



