一、题目

二、题解
1. 思路
双向链表 + 哈希表。
哈希表用于快速查找是否存在值,表中存放链表节点 - key;双向链表用于快速确定最近使用情况,链表节点存放key和value。
每次访问时,将节点移动到链表头部,当内部节点超出容量时,删掉尾部节点。
2. 题解
java
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<Integer, DLinkedNode>();
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.prev = head;
}
public int get(int key) {
// 查询key
DLinkedNode findNode = cache.get(key);
// 若无该节点
if(findNode == null){
return -1;
} else {
// 有key ------ 返回value
moveToHead(findNode);
return findNode.value;
}
}
public void put(int key, int value) {
DLinkedNode node = cache.get(key);
if(node == null){
// 如果不存在,先插入,再判断是否空间溢出
DLinkedNode newNode = new DLinkedNode(key, value);
cache.put(key, newNode);
addToHead(newNode);
size++;
if(size > Capacity) {
DLinkedNode tailNode = removeTailNode();
cache.remove(tailNode.key);
size--;
}
} else {
// 如果存在,则更新value
node.value = value;
moveToHead(node);
}
}
// 移除节点
private void removeNode(DLinkedNode node){
node.prev.next = node.next;
node.next.prev = node.prev;
}
// 在头部插入节点
private void addToHead(DLinkedNode node){
node.next = head.next;
head.next.prev = node;
head.next = node;
node.prev = head;
}
// 将节点挪到头部
private void moveToHead(DLinkedNode node){
removeNode(node);
addToHead(node);
}
// 删除尾部节点
private DLinkedNode removeTailNode(){
DLinkedNode res = tail.prev;
removeNode(res);
return res;
}
}
/**
* 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);
*/