hashmap+双向链表
class LRUCache {
//定义一个双向链表
class DLinkedNode {
int key;
int value;
DLinkedNode prev;
DLinkedNode next;
public DLinkedNode() {}
public DLinkedNode(int _key, int _value) {key = _key; value = _value;}
}
//定义一个哈希表
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();
//头节点的next指向尾节点,尾节点的prev指向头节点
head.next = tail;
tail.prev = head;
}
public int get(int key) {
// 从哈希表中获取key对应的节点
DLinkedNode node = cache.get(key);
// 如果节点为空,返回-1
if (node == null) {
return -1;
}
// 如果节点不为空,将节点移动到链表的头部
moveToHead(node);
// 返回节点的值
return node.value;
}
public void put(int key, int value) {
// 从哈希表中获取key对应的节点
DLinkedNode node = cache.get(key);
// 如果节点为空
if (node == null) {
// 创建一个新的节点
DLinkedNode newNode = new DLinkedNode(key, value);
// 将节点添加到哈希表中
cache.put(key, newNode);
// 将节点添加到链表的头部
addToHead(newNode);
// 计数器加1
size++;
// 如果计数器大于容量
if (size > capacity) {
// 删除链表的尾部节点
DLinkedNode tail = removeTail();
// 删除哈希表中的尾部节点
cache.remove(tail.key);
// 计数器减1
size--;
}
} else {
// 如果节点不为空,更新节点的值
node.value = value;
// 将节点移动到链表的头部
moveToHead(node);
}
}
//将节点移动到链表的头部
private void moveToHead(DLinkedNode node)
{
//先将节点从链表中删除
removeNode(node);
//再将节点添加到链表的头部
addToHead(node);
}
//将节点添加到链表的头部
private void addToHead(DLinkedNode node)
{
//将节点的前驱指向头节点
node.prev = head;
//将节点的后继指向头节点的后继
node.next = head.next;
//将头节点的后继的前驱指向节点
head.next.prev = node;
//将头节点的后继指向节点
head.next = node;
}
//将节点从链表中删除
private void removeNode(DLinkedNode node)
{
//将节点的前驱的后继指向节点的后继
node.prev.next = node.next;
//将节点的后继的前驱指向节点的前驱
node.next.prev = node.prev;
}
//删除链表的尾部节点
private DLinkedNode removeTail()
{
//获取尾节点的前驱
DLinkedNode node = tail.prev;
//将尾节点的前驱的前驱的后继指向尾节点
tail.prev.prev.next = tail;
//将尾节点的前驱指向尾节点的前驱的前驱
tail.prev = tail.prev.prev;
//返回尾节点的前驱
return node;
}
}