题目分析
- LRU是操作系统常用的一种页面置换算法,选择最近最久未使用的页面予以淘汰
- 虚拟头尾节点
- 哈希表+双向链表
Solution
public class LRUCache {
private Map<Integer, Node> map;
private int capacity;
// 虚拟头结点
private Node first;
// 虚拟尾结点
private Node last;
public LRUCache(int capacity) {
map = new HashMap<>(capacity);
this.capacity = capacity;
first = new Node();
last = new Node();
first.next = last;
last.prev = first;
}
public int get(int key) {
Node node = map.get(key);
if (node == null) return -1;
removeNode(node);
addAfterFirst(node);
return node.value;
}
/**
* @param node 将node节点插入到first节点的后面
如果先维护node与first,那么node和first.next就取不到联系,因为first和first.next联系已经断了
*/
private void addAfterFirst(Node node) {
// node与first.next
node.next = first.next;
first.next.prev = node;
// node与first
first.next = node;
node.prev = first;
}
/**
* @param node 从双向链表中删除node节点
*/
private void removeNode(Node node) {
node.next.prev = node.prev;
node.prev.next = node.next;
}
public void put(int key, int value) {
Node node = map.get(key);
if (node != null) { // 更新key-value
node.value = value;
removeNode(node);
} else { // 添加一对新的key-value
if (map.size() == capacity) {
// 淘汰最近最少使用的node\
removeNode(map.remove(last.prev.key));
}
map.put(key, node = new Node(key, value));
}
addAfterFirst(node);
}
private static class Node {
public int key;
public int value;
public Node prev;
public Node next;
public Node(int key, int value) {
this.key = key;
this.value = value;
}
public Node() {}
}
}
Reference:小码哥MJ