题目描述
设计并实现一个满足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)。
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Objects;
class LRUCache {
private Integer capacity;
private HashMap<Integer, Node> cacheMap;
private Node head;
private Node tail;
public LRUCache(Integer capacity){
this.capacity = capacity;
cacheMap = new HashMap<>(capacity);
head = new Node(-1,-1);
tail = new Node(-100,-1);
head.next = tail;
tail.pre = head;
}
public int get(Integer key){
if (cacheMap.containsKey(key)){
// 移动该节点到头部
moveNodeToFirst(cacheMap.get(key));
return cacheMap.get(key).value;
}
return -1;
}
public void put(Integer key,Integer value){
if (cacheMap.containsKey(key)){
// 移除key所在的节点
removeNode(cacheMap.get(key));
}else if (cacheMap.size() == capacity){
// 链表最后一个节点的值last
Node lastNode = tail.pre;
// 移除cacheMap缓存中的last
cacheMap.remove(lastNode.key);
// 移除链表最后一个节点
removeNode(lastNode);
}
// 链表头增加该节点
Node newNode = new Node(key,value);
addFirst(newNode);
cacheMap.put(key, newNode);
}
private void removeNode(Node node){
node.pre.next = node.next;
node.next.pre = node.pre;
}
private void addFirst(Node node){
node.next = head.next;
head.next.pre = node;
head.next = node;
node.pre = head;
}
private void moveNodeToFirst(Node node){
removeNode(node);
addFirst(node);
}
public class Node{
Node pre;
Node next;
Integer value;
Integer key;
public Node(){
}
public Node(Integer key,Integer value){
this.value = value;
this.key = key;
}
}
}
该代码实现了一个LRU缓存的数据结构。使用HashMap和双向链表实现缓存的存储和访问。其中,cacheMap用于存储缓存的键值对,head和tail节点分别表示链表的头部和尾部。
构造方法LRUCache:初始化LRU缓存,指定容量capacity,并初始化cacheMap、head和tail。
get方法:根据给定的关键字key获取缓存中对应的值,并将该节点移动到链表头部。
put方法:如果关键字key已经存在,则更新其对应的值;如果不存在,则将新的键值对插入缓存。如果插入操作导致缓存超过容量,需要逐出最久未使用的关键字。
以上文字和代码由chatgpt整理。
N刷熟能生巧,特别顺