这里写目录标题
1、LRU缓存机制【2.18】
1、双向链表+哈希表
使用双向链表+哈希表来实现LRU,我们使用双向链表来存储数据,然后借助哈希表来进行快速查找某个节点是否在双向链表中,使用双向链表的目的是快速拿到前驱节点,保证操作的时间复杂度为 O(1)。
步骤:
1、实现一个双向链表节点类
2、实现一个双向链表类
3、实现LRU的get方法和put方法
class LRUCache {
private HashMap<Integer, Node> map;
private DoubleList cache;
private int capacity;
public LRUCache(int capacity) {
map = new HashMap();
cache = new DoubleList();
this.capacity = capacity;
}
public int get(int key) {
//如果不存在,返回-1;如果存在返回val,并将该节点重新加入链表
if(!map.containsKey(key)) return -1;
int val = map.get(key).val;
put(key, val);
return val;
}
public void put(int key, int value) {
//如果该节点已经在链表中,删除链表中的该节点,然后重新加入链表,并更新map;如果该节点不在链表中,将该节点头插进链表,并将其存进map中
Node node = new Node(key, value);
if(map.containsKey(key)) {
cache.remove(map.get(key));
cache.addFirst(node);
map.put(key, node);
} else {
if(capacity == cache.size()) {
//删除尾节点
Node last = cache.removeLast();
map.remove(last.key);
}
cache.addFirst(node);
map.put(key, node);
}
}
}
class DoubleList {
private Node head, tail;
private int size;
public DoubleList() {
head = new Node(-1, -1);
tail = new Node(-1, -1);
size = 0;
head.next = tail;
tail.prev = head;
}
public void addFirst(Node node) {
Node headNext = head.next;
head.next = node;
headNext.prev = node;
node.prev = head