35.LRU缓存
cpp
class LRUCache {
//手写双链表 自己完整独立的写写,好吧,加油。实在写不出再看题解
//双向链表
private static class Node{
int key,value;
Node prev,next;
//写初始化方法
Node(int k, int v){
key = k;
value = v;
}
}
private final int capacity;
private final Node dummy = new Node(0,0);
private final Map<Integer,Node> key2Node = new HashMap<>();
public LRUCache(int capacity) {
this.capacity = capacity;
//这里还要对dummy进行前后指针的初始化
dummy.next = dummy;
dummy.prev = dummy;
}
//需要返回关键字的值
public int get(int key) {
//查询该关键字是否存在对应节点,若存在,将该节点删除而后将该节点放到链表开头,返回关键字的值(也就是节点的值);若不存在则返回-1
//优化一下,既然get和put都需要去先删除再置顶:写函数getnode,该函数先将节点删除,而后将其置顶
//再写一个删除节点的函数就好
Node key2node = getNode(key);
if(key2node==null) return -1;
else return key2node.value;
}
public void put(int key, int value) {
Node key2node = getNode(key);
//修改key对应的值为value
if(key2node!=null){
key2node.value = value;
}
else{
if(key2Node.size() >= capacity){
//双向有环链表,找头部就是dummy.next;找尾部就是dummy.prev
Node lastNode = dummy.prev;
remove(lastNode);
//哈希表删除一个
key2Node.remove(lastNode.key);
//把新节点放到头部
Node putnewNode = new Node(key,value);
push2head(putnewNode);
//哈希表插入一个
key2Node.put(key,putnewNode);
}
else{
Node node = new Node(key,value);
push2head(node);
key2Node.put(key,node);
}
}
}
//getNode()
private Node getNode(int key){
if(key2Node.containsKey(key)){
Node node = key2Node.get(key);
remove(node);
push2head(node);
return node;
}
else return null;
}
//remove()
private void remove(Node node){
node.next.prev = node.prev;
node.prev.next = node.next;
}
//push2head
private void push2head(Node x){
x.next = dummy.next;
x.prev=dummy;
dummy.next.prev=x;
dummy.next=x;
//x.prev=dummy;
//x.next=dummy.next;
//x.prev.next=x;
//x.next.prev=x;
}
}
/**
* 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);
*/