LRU (Least recently used) 最近最少使用
像浏览器的缓存策略、memcached的缓存策略都是使用LRU这个算法,LRU算***将近期最不会访问的数据淘汰掉。LRU如此流行的原因是实现比较简单,而且对于实际问题也很实用,良好的运行时性能,命中率较高。下面谈谈如何实现LRU缓存:
- 新数据插入到链表头部
- 每当缓存命中(即缓存数据被访问),则将数据移到链表头部
- 当链表满的时候,将链表尾部的数据丢弃
LRU Cache具备的操作:
- set(key,value):如果key在hashmap中存在,则先重置对应的value值,然后获取对应的节点cur,将cur节点从链表删除,并移动到链表的头部;若果key在hashmap不存在,则新建一个节点,并将节点放到链表的头部。当Cache存满的时候,将链表最后一个节点删除即可。
- get(key):如果key在hashmap中存在,则把对应的节点放到链表头部,并返回对应的value值;如果不存在,则返回-1。
解法1:使用队列和map实现
opt == 1 : 添加(x, y)
opt == 1 : 确定map中是否存在(x, y),如果存在queue先移除(x, y)再添加(x, y),达到移除最不经常使用的记录
size > k : 移除队列首元素即可
import java.util.*;
public class Solution {
/**
* lru design
* @param operators int整型二维数组 the ops
* @param k int整型 the k
* @return int整型一维数组
*/
public int[] LRU (int[][] operators, int k) {
// write code here
ArrayList<Integer> list=new ArrayList<Integer>();
Queue<int[]> queue=new LinkedList<int[]>();
HashMap<Integer,int[]> map=new HashMap<Integer,int[]>();
for(int i=0;i<operators.length;i++){
if(queue.size()>k){
int[] poll=queue.poll();
map.remove(poll[1]);
}
if(operators[i][0]==1){
// int[] res=map.get(operators[i][1]);
// if(res!=null){
// map.remove(operators[i][1]);
// queue.remove(res);
// }
map.put(operators[i][1],operators[i]);
queue.offer(operators[i]);
}
if(operators[i][0]==2){
int[] res=map.get(operators[i][1]);
if(res!=null){
queue.remove(res);
queue.offer(res);
list.add(res[2]);
}
else{
list.add(-1);
}
}
}
int[] result=new int[list.size()];
for(int i=0;i<list.size();i++){
result[i]=list.get(i);
}
return result;
}
}
京公网安备 11010502036488号