step by step.
题目:
请你设计并实现一个满足 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", "put", "put", "get", "put", "get", "put", "get", "get", "get"] [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]] 输出 [null, null, null, 1, null, -1, null, -1, 3, 4] 解释 LRUCache lRUCache = new LRUCache(2); lRUCache.put(1, 1); // 缓存是 {1=1} lRUCache.put(2, 2); // 缓存是 {1=1, 2=2} lRUCache.get(1); // 返回 1 lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3} lRUCache.get(2); // 返回 -1 (未找到) lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3} lRUCache.get(1); // 返回 -1 (未找到) lRUCache.get(3); // 返回 3 lRUCache.get(4); // 返回 4
思路:
主要是置换算法
·去重 => 想到哈希HashMap
·更新最新使用的 => 想到顺序结构 => LinkedHashMap
超详细LinkedHashMap解析_求offer的菜鸡的博客-CSDN博客文章目录LinkedHashMap概述LinkedHashMap原理主要元素构造函数维护链表的操作afterNodeRemovalafterNodeAccessafterNodeInsertionget操作put操作HashMap#putVal(...)Remove操作HashMap#removeNode(...)LinkedHashMap用作实现LRU总结LinkedHashMap概述pub..._linkedhashmaphttps://blog.csdn.net/qq_40050586/article/details/105851970?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169113277716800227460532%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=169113277716800227460532&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-105851970-null-null.142^v92^controlT0_2&utm_term=linkedhashmap&spm=1018.2226.3001.4187
代码:
class LRUCache {
LinkedHashMap<Integer,Integer> hs;
int cap;
public LRUCache(int capacity) {
hs = new LinkedHashMap<Integer,Integer>();
this.cap = capacity;
}
public int get(int key) {
if(this.hs.containsKey(key)) {
mKRecent(key,hs.get(key));
return hs.get(key);
}
else return -1;
}
public void put(int key, int value) {
if(hs.containsKey(key)){
hs.put(key,value);
mKRecent(key,value);
return;
}
if(hs.size()==this.cap){
//over
hs.remove(hs.keySet().iterator().next());
}
hs.put(key,value); //插入队尾,更新最新
}
public void mKRecent(int key,int value){
//重置,主要目的:插入队尾
hs.remove(key);
hs.put(key,value);
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/