HashMap+双向链表实现LRU算法
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity)以 正整数 作为容量capacity初始化 LRU 缓存int get(int key)如果关键字key存在于缓存中,则返回关键字的值,否则返回-1。void put(int key, int value)如果关键字key已经存在,则变更其数据值value;如果不存在,则向缓存中插入该组key-value。如果插入操作导致关键字数量超过capacity,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
class LRUCache {
// LRU缓存 最近最少使用---思路:用双链表来模拟,HashMap来
int capacity; //容量
DoubleList cache;
HashMap<Integer,Node> map;
//初始化
public LRUCache(int capacity) {
this.capacity = capacity;
cache = new DoubleList();
map = new HashMap<>();
}
//如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1
public int get(int key) {
if(map.containsKey(key)){
//如果存在,调整顺序
Node tempNode = map.get(key);
cache.remove(tempNode);
cache.addLast(tempNode);
return tempNode.val;
}else{
return -1;
}
}
//如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value
public void put(int key, int value) {
if(map.containsKey(key)){
//如果存在
Node tempNode = map.get(key);
cache.remove(tempNode);
Node newNode = new Node(key,value);
map.put(key,newNode);
cache.addLast(newNode);
}else{
//如果不存在
//判断满了没有
if(map.size()==capacity){
//满了--删除最久没访问的
Node first = cache.removeFirst();
map.remove(first.key);
//再新添加
}
//如果没满
Node node = new Node(key,value);
map.put(key,node);
cache.addLast(node);
}
}
//定义双向链表的节点
class Node{
int key;
int val;
Node pre;
Node next;
//构造
public Node(int key,int val){
this.key = key;
this.val = val;
}
}
//定义双向链表
class DoubleList{
int size;
Node head,tail;
public DoubleList(){
//初始化链表
head = new Node(0,0);
tail = new Node(0,0);
head.next = tail;
tail.pre = head;
size = 0;
}
//末尾添加节点
public void addLast(Node x){
tail.pre.next = x;
x.pre=tail.pre;
x.next = tail;
tail.pre = x;
size++;
}
//删除最近没访问的节点并且返回这个节点--head是虚拟头节点
public Node removeFirst(){
Node first = head.next;
head.next = head.next.next;
head.next.pre=head;
size--;
return first;
}
//删除指定节点
public void remove(Node node){
node.pre.next=node.next;
node.next.pre=node.pre;
size--;
}
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/