LRU缓存——leetcode134
LRU缓存
描述
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。实现 LRUCache 类:
- LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
- int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
- void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
样例
输入:
LRUCache(2)
set(2, 1)
set(1, 1)
get(2)
set(4, 1)
get(1)
get(2)
输出:[1,-1,1]
题解:Map+List
Map: 存储key-value
LinkedList: 按最近最先使用存储key值。数据结构:[新值,较新值,旧值],利用addFirst使得头部的值最新
class LRUCache0 {
private Map<Integer, Integer> nums;
private LinkedList<Integer> list;
private int capacity;
public LRUCache0(int capacity) {
nums = new HashMap<>();
list = new LinkedList<>();
this.capacity = capacity;
}
/**
* 获取数据:
* @param key 数据key
* @return 如果存在key,则返回value,否则返回-1
*/
public int get(int key) {
if(!nums.containsKey(key)) return -1;
list.remove(Integer.valueOf(key));
list.addFirst(key);
return nums.get(key);
}
/**
* 写入数据:
* 1. 没有key,则插入数值
* 2. 如果有key, 则更新value
* 2. 如果缓存到达上限,则删除最近最少使用的数据,在插入
* @param key 数据key
* @param value 数据值
*/
public void set(int key, int value) {
if(nums.containsKey(key)) {
nums.put(key, value);
list.remove(Integer.valueOf(key));
list.addFirst(key);
}else {
if(list.size() == capacity) {
Integer dKey = list.remove(list.size() - 1);
nums.remove(dKey);
}
nums.put(key,value);
list.addFirst(key);
}
}
}
题解: LinkedHashMap
LinkedHashMap: 有序的Map, 即可以存key-value,又可以有序取值。
数据结构: [旧值,较新值,新值], 利用put将最新的值放在最后
class LRUCache {
private LinkedHashMap<Integer, Integer> nums;
private int capacity;
public LRUCache(int capacity) {
this.capacity = capacity;
nums = new LinkedHashMap<>();
}
public int get(int key) {
if(!nums.containsKey(key)) return -1;
int value = nums.remove(key);
nums.put(key, value);
return value;
}
public void set(int key, int value) {
if(nums.containsKey(key)) {
nums.remove(key);
nums.put(key, value);
}else {
if(nums.size() == capacity) {
nums.remove(nums.keySet().iterator().next());
}
nums.put(key, value);
}
}
}