Leetcode——LRU 缓存机制
Posted Yawn,
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode——LRU 缓存机制相关的知识,希望对你有一定的参考价值。
1. 题目
2. 题解
双链表中实现的方法:
- 链表初始化
- 添加元素到双链表尾部(同时意味着该元素最近使用过)
- 删除某个结点(非头结点)
- 删除并返回头结点(意味着移除最久未使用过的元素)
- 返回链表当前长度
LRU 缓存中的方法:
- 1.初始化,get,put方法
- 2.设置某元素最近已使用makeRecently(原map中已有该元素)
- 3.添加最近使用过的元素addRecently(原map中不存在该键值对,新元素)
- 4.删除某个key对应的元素
- 5.删除最久未使用过的元素 2.中的方法也可以直接在get和put方法中实现,可以减少部分冗余
class LRUCache {
class DLinkedNode {
int key;
int value;
DLinkedNode pre;
DLinkedNode next;
public DLinkedNode() {};
public DLinkedNode(int ikey, int ivalue) {
key = ikey;
value = ivalue;
}
}
private Map<Integer, DLinkedNode> cache = new HashMap<>();
private int size;
private int capacity;
private DLinkedNode head, tail;
public LRUCache(int capacity) {
this.size = 0;
this.capacity = capacity;
head = new DLinkedNode();
tail = new DLinkedNode();
// 使用伪头部和伪尾部节点,减少边界判断
head.next = tail;
tail.pre = head;
}
public int get(int key) {
DLinkedNode node = cache.get(key);
if(node == null)
return -1;
// 如果 key 存在,先通过哈希表定位,再移到头部
moveToHead(node);
return node.value;
}
public void put(int key, int value) {
DLinkedNode node = cache.get(key);
if (node == null) {
// 如果 key 不存在,创建一个新的节点
DLinkedNode newNode = new DLinkedNode(key, value);
// 添加进哈希表
cache.put(key, newNode);
// 添加至双向链表的头部
addToHead(newNode);
size++;
if (size > capacity) {
// 如果超出容量,删除双向链表的尾部节点
DLinkedNode tail = removeTail();
// 删除哈希表中对应的项
cache.remove(tail.key);
size--;
}
} else {
node.value = value;
moveToHead(node);
}
}
private void addToHead(DLinkedNode node) { //插入至头结点
node.pre = head;
node.next = head.next;
node.next.pre = node;
head.next = node;
}
private void removeNode(DLinkedNode node) { //删该节点结点
node.pre.next = node.next;
node.next.pre = node.pre;
}
private void moveToHead(DLinkedNode node) { //移动到头结点:删该节点,插入到头结点
removeNode(node);
addToHead(node);
}
private DLinkedNode removeTail() { //移除尾节点
DLinkedNode res = tail.pre; //尾节点的前一个就是真正的尾节点
removeNode(res);
return res; //返回尾节点是为了对应删除Map中的节点
}
}
/**
* 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);
*/
以上是关于Leetcode——LRU 缓存机制的主要内容,如果未能解决你的问题,请参考以下文章