这里是题目描述:LeetCode-146.LRU缓存机制
用哈希链表实现LRU缓存机制可以满足在 O(1) 的时间开销下完成获取数据get
和写入数据put
。因此我们设计实验哈希链表来实现缓存机制:
题解代码:
class LRUCache
{
public Node head; //Node链表的头尾节点
public Node end;
private HashMap<Integer,Node> hashMap; //存储LRU缓存内容键值对的HashMap,用于快速根据Key找到链表中对应的节点
private int capacity;
private int occupy;
public LRUCache(int capacity)
{
this.capacity=capacity;
occupy=0;
hashMap=new HashMap<>();
}
public int get(int key)
{
if(hashMap.containsKey(key))
{
Node node=hashMap.get(key);
if(end!=node) //如果访问的是尾结点,不用更新位置
{
if(head==node)
{
head=node.next;
}
node.updateNode(end);
end=node;
}
return node.getValue();
}
else
{
return -1;
}
}
public void put(int key, int value)
{
if(hashMap.containsKey(key)) //若cache中存在相同key值节点,只需更改value
{
hashMap.get(key).value=value;
this.get(key);
}
else
{
if(occupy==capacity) //当容量已满,需要移除head指针出节点,并从hashMap中移除
{
Node removedNode=head;
head=head.next;
removedNode.removeNode();
if(end==removedNode)
{
end=null;
}
hashMap.remove(removedNode.getKey());
occupy--;
}
Node node=new Node(value,key);
node.updateNode(end);
end=node;
if(head==null)
{
head=node;
}
hashMap.put(key,node);
occupy++;
}
}
}
class Node
{
int value;
int key;
Node pre;
Node next;
public Node(int value,int key)
{
this.value=value;
this.key=key;
this.pre=null;
this.next=null;
}
public int getKey()
{
return key;
}
public int getValue()
{
return value;
}
public void updateNode(Node end) //更新节点的位置,将节点移到链表的尾部(最近访问位置)
{
if(this.pre!=null)
{
this.pre.next=this.next;
}
if(this.next!=null)
{
this.next.pre=this.pre;
}
this.next=null;
if(end!=null)
{
end.next=this;
}
this.pre=end;
}
public void removeNode() //将节点从链表中移除(只有链表中的头结点会被移除)
{
if(this.next!=null)
{
this.next.pre=null;
}
this.next=null;
}
}