面试高频LRU,图文解释
思路,代码已经通过leetcode 检测
先看图,在看代码(图看明白了,才能看懂代码)
public class LRUCache {
private int capacity;
private HashMap<Integer, CacheNode> nodesMap = new HashMap<>();
// 定义俩个节点,用来串起整个双向链表 head 和tail的作用见图
private CacheNode head = new CacheNode(-1, -1);
private CacheNode tail = new CacheNode(-1, -1);
class CacheNode {
int key;
int value;
CacheNode prev;
CacheNode next;
public CacheNode() {
}
public CacheNode(int key, int value) {
this.key = key;
this.value = value;
}
}
//定义lru容量
public LRUCache(int capacity) {
this.capacity = capacity;
tail.prev = head;
head.next = tail;
}
//查询
public int get(int key) {
if (!nodesMap.containsKey(key)) {
return -1;
}
CacheNode cacheNode = nodesMap.get(key);
cacheNode.prev.next = cacheNode.next;
cacheNode.next.prev = cacheNode.prev;
movetoTail(cacheNode);
return cacheNode.value;
}
//插入方法
public void put(int key, int value) {
//1.包含
if (get(key) != -1) {
nodesMap.get(key).value = value;
return;
}
if (nodesMap.size() == capacity) {
//移除第一个
nodesMap.remove(head.next.key);
head.next = head.next.next;
head.next.prev = head;
}
CacheNode insert = new CacheNode(key, value);
nodesMap.put(key, insert);
movetoTail(insert);
}
private void movetoTail(CacheNode node) {
CacheNode prev = tail.prev;
//先解决新的接口node 的前后指针
node.next = tail;
node.prev = prev;
// 解决 tail 和3的指针问题
tail.prev = node;
prev.next = node;
}
}