题目
方法一:双向链表+HashMap
public class LRUCache {
//定义双向链表,靠近头的是最近使用的,靠近尾的是最久未使用的。
//定义HashMap,存储链表节点信息
class LinkNode {
int key;
int value;
LinkNode prev;
LinkNode next;
public LinkNode() {}
public LinkNode(int key, int value) {
this.key = key;
this.value = value;
}
}
private Map<Integer, LinkNode> map = new HashMap<>();
private int size;
private int capacity;
private LinkNode head, tail;
public LRUCache(int capacity) {
this.capacity = capacity;
this.size = 0;
head = new LinkNode();
tail = new LinkNode();
head.next = tail;
tail.prev = head;
}
public int get(int key) {
LinkNode node = map.get(key);
if (node == null) {
return -1; //不存在返回-1
}
//存在需移动位置至链表头部
moveNodeToHead(node);
return node.value;
}
public void put(int key, int value) {
LinkNode node = map.get(key);
if (node != null) {
node.value = value;
//node移动位置至链表头部
moveNodeToHead(node);
} else {
LinkNode n = new LinkNode(key, value);
map.put(key, n);
//新node添加至链表头部
addHead(n);
size++;
if (size > capacity) {
//逐出最久未使用的node
rmTailNode();
size--;
}
}
}
private void moveNodeToHead(LinkNode node) {
removeNode(node); //删除节点
addHead(node); //添加至头节点
}
private void rmTailNode() {
map.remove(tail.prev.key);
removeNode(tail.prev);
}
private void removeNode(LinkNode node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void addHead(LinkNode node) {
head.next.prev = node;
node.prev = head;
node.next = head.next;
head.next = node;
}
}
LeetCode测试结果