【重难点】【数据结构 03】LRU
文章目录
一、LRU
LRU(Least Recently Used,最近最少使用),这个算法的思想就是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小
这里我们使用 HashMap + 双向链表来实现
package com.sisyphus.lru;
import java.util.HashMap;
import java.util.Map;
public class LRUCache {
private Map<Integer, DoubleLinkedNode> cache = new HashMap<Integer, DoubleLinkedNode>();
private int size;
private int capacity;
private DoubleLinkedNode head;
private DoubleLinkedNode tail;
public LRUCache(int capacity) {
this.capacity = capacity;
size = 0;
head = new DoubleLinkedNode();
tail = new DoubleLinkedNode();
head.next = tail;
tail.prev = head;
}
public int get(int key){
DoubleLinkedNode node = cache.get(key);
if(node == null){
return -1;
}
moveToHead(node);
return node.value;
}
public void put(int key, int value){
DoubleLinkedNode node = cache.get(key);
if(node == null){
DoubleLinkedNode newNode = new DoubleLinkedNode(key, value);
cache.put(key, newNode);
addToHead(newNode);
size++;
if(size > capcity){
DoubleLinkedNode tail = removeTail();
cache.remove(tail.key);
size--;
}
}else{
node.value = value;
moveToHead(node);
}
}
private void addToHead(DoubleLinkedNode node){
node.prev = head;
node.next = head.next;
head.next.prev = node;
head.next = node;
}
private void removeNode(DoubleLinkedNode node){
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void moveToHead(DoubleLinkedNode node){
removeNode(node);
addToHead(node);
}
private DoubleLinkedNode removeTail(){
DoubleLinkedNode res = tail.prev;
removeNode(res);
return res;
}
}
class DoubleLinkedNode{
int key;
int value;
DoubleLinkedNode prev;
DoubleLinkedNode next;
public DoubleLinkedNode() {
}
public DoubleLinkedNode(int key, int value) {
this.key = key;
this.value = value;
}
}
//get 和 put 的时间复杂度都为 O(1)
//空间复杂度为 O(n)