import java.util.HashMap;
import java.util.Map;
class LRUCache {
// 双向链表
static class MyLinkedNode {
private int key;
private int value;
MyLinkedNode pre;
MyLinkedNode next;
MyLinkedNode(){}
MyLinkedNode(int key, int value) {
this.key = key;
this.value = value;
}
}
// Map,用于定位指定key的节点在链表中的位置
private Map<Integer, MyLinkedNode> cache;
private int size;
private int capacity;
// 头尾节点
private MyLinkedNode head, tail;
public LRUCache(int capacity) {
this.size = 0;
this.capacity = capacity;
cache = new HashMap<>(capacity);
head = new MyLinkedNode();
tail = new MyLinkedNode();
head.next = tail;
tail.pre = head;
}
public int get(int key) {
// 先获取对应的节点
MyLinkedNode node = cache.get(key);
if (node == null) {
return -1;
}
// 删除表中的该节点
node.pre.next = node.next;
node.next.pre = node.pre;
// 将节点移到头部
moveNodeToHead(node);
return node.value;
}
public void put(int key, int value) {
MyLinkedNode node = cache.get(key);
if (node == null) {
// 不存在
MyLinkedNode newNode = new MyLinkedNode(key, value);
cache.put(key, newNode);
size++;
if (size > capacity) {
// 先删除最近未使用的数据
MyLinkedNode n = tail.pre;
n.pre.next = tail;
tail.pre = n.pre;
cache.remove(n.key);
size--;
}
moveNodeToHead(newNode);
} else {
// 存在,更新值
node.value = value;
// 删除原表的节点
node.pre.next = node.next;
node.next.pre = node.pre;
moveNodeToHead(node);
}
}
private void moveNodeToHead(MyLinkedNode node) {
node.pre = head;
node.next = head.next;
head.next.pre = node;
head.next = node;
}
}
/**
* 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);
*/
总结
本题只有多练多思考,又一个纠结点就是 节点赋值问题,
node.pre = head;
node.next = head.next;
head.next.pre = node;
head.next = node;
这个在本科刚学那会是我的强项,看来是有必要再捡起来复习一下了