class LRUCache {
class DataNode{
int key, val;
DataNode pre, next;
public DataNode(int k, int v){
key = k;
val = v;
pre = null;
next = null;
}
public DataNode(){
key = -1;
val = -1;
pre = null;
next = null;
}
}
DataNode head, tail;
Map<Integer, DataNode> nodes;
int cap;
private void addNode(DataNode newNode){
tail.pre.next = newNode;
newNode.pre = tail.pre;
newNode.next = tail;
tail.pre = newNode;
nodes.put(newNode.key, newNode);
}
private void delNode(DataNode oldNode){
oldNode.pre.next = oldNode.next;
oldNode.next.pre = oldNode.pre;
nodes.remove(oldNode.key);
}
public LRUCache(int capacity) {
cap = capacity;
head = new DataNode();
tail = new DataNode();
head.next = tail;
tail.pre = head;
nodes = new HashMap<>();
}
public int get(int key) {
if(nodes.containsKey(key)){
DataNode oldNode = nodes.get(key);
delNode(oldNode);
DataNode newNode = new DataNode(oldNode.key, oldNode.val);
addNode(newNode);
return newNode.val;
}
return -1;
}
public void put(int key, int value) {
boolean exist = false;
if(nodes.containsKey(key)){
DataNode oldNode = nodes.get(key);
delNode(oldNode);
exist = true;
}
if(nodes.size() == cap){
if(!exist) {
delNode(head.next);
}
}
DataNode newNode = new DataNode(key, value);
addNode(newNode);
}
}
/**
* 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);
*/