Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
Solution
public class LRUCache {
public class Node {
public int key;
public int value;
public Node prev;
public Node next;
};
Map<Integer, Node> map;
int cap;
Node head, tail;
public LRUCache(int capacity) {
map = new HashMap<Integer, Node>();
cap = capacity;
head = new Node();
tail = new Node();
head.prev = null;
head.next = tail;
tail.prev = head;
tail.next = null;
}
public int get(int key) {
if(map.containsKey(key)) {
Node node = map.get(key);
deleteNode(node);
insertToHead(node);
return map.get(key).value;
}
else return -1;
}
public void deleteNode(Node node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
public void insertToHead(Node node) {
node.next = head.next;
head.next.prev = node;
head.next = node;
node.prev = head;
}
public void set(int key, int value) {
if(map.containsKey(key)) {
Node node = map.get(key);
node.value = value;
deleteNode(node);
insertToHead(node);
} else {
Node newNode = new Node();
newNode.key = key;
newNode.value = value;
map.put(key, newNode);
insertToHead(newNode);
if(map.keySet().size() > cap) {
map.remove(tail.prev.key);
deleteNode(tail.prev);
}
}
}
}