// LRU缓冲算法
// 面试经典题,使用hashmap+双向链表实现
// put时查找是否key已在map中,已经存在,修改值,并放入链表头
// 不存在时,创建新节点,插入链表头, 当超过容量时,移除链表尾节点,并从map中删除映射
// get时如果map中没查到,返回-1 ,如果查到, 返回值,并提前到链表头
class LRUCache {
class ListNode {
private int key;
private int val;
private ListNode pre;
private ListNode next;
ListNode() {
}
ListNode(int key ,int val) {
this.key = key;
this.val = val;
pre = null;
next = null;
}
}
private HashMap<Integer, ListNode> cache;
private ListNode head;
private ListNode tail;
private int size;
private int cap;
public LRUCache(int capacity) {
size = 0;
cap = capacity;
cache = new HashMap<Integer, ListNode>();
head = new ListNode();
tail = new ListNode();
head.next = tail;
tail.pre = head;
}
public int get(int key) {
if (!cache.containsKey(key))
return -1;
ListNode node = cache.get(key);
moveToHead(node);
return node.val;
}
public void put(int key, int value) {
if (cache.containsKey(key)) {
ListNode node = cache.get(key);
node.val = value;
moveToHead(node);
}else {
ListNode node = new ListNode(key, value);
size++;
if (size > cap) {
int tmp = removeTail();
cache.remove(tmp);
size--;
}
addNode(node);
cache.put(key, node);
}
}
private void addNode(ListNode node) {
node.pre = head;
node.next = head.next;
head.next.pre = node;
head.next = node;
}
private void removeNode(ListNode node) {
node.pre.next = node.next;
node.next.pre = node.pre;
}
private void moveToHead(ListNode node) {
removeNode(node);
addNode(node);
}
private int removeTail() {
ListNode node = tail.pre;
removeNode(node);
return node.key;
}
}
Leetcode 146 缓存算法 hashmap+双向链表
于 2022-07-02 22:00:23 首次发布