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.
如果要保证O(1)的读取,那么肯定是要用hashmap来存储键值对的;同时又要维护一个队列,并保证插入队首和删除一个node都是O(1),则需要一个double linked list。因此建立一个Node类作为双链表的node,存储key, value, prev和next.
public class LRUCache {
private Map<Integer, Node> map;
private Node head;
private Node tail;
private int capacity;
private int count;
public LRUCache(int capacity) {
map = new HashMap<Integer, Node>();
this.capacity = capacity;
head = null;
tail = null;
count = 0;
}
private void setHead(Node node){
node.next = head;
node.prev = null;
if(head != null){
head.prev = node;
}
head = node;
if(tail == null){
tail = head;
}
}
private void deleteNode(Node node){
if(node.prev != null){
node.prev.next = node.next;
}
else{
head = node.next;
}
if(node.next != null){
node.next.prev = node.prev;
}
else{
tail = node.prev;
}
}
public int get(int key) {
if(map.containsKey(key)){
Node node = map.get(key);
deleteNode(node);
setHead(node);
return node.value;
}
else
return -1;
}
public void set(int key, int value) {
if(map.containsKey(key)){
Node node = map.get(key);
node.value = value;
deleteNode(node);
setHead(node);
}
else{
Node node = new Node(key, value);
if(count < capacity){
map.put(key, node);
setHead(node);
count++;
}
else{
//deleteNode(tail);
map.remove(tail.key);
tail = tail.prev;
if(tail != null)
tail.next = null;
map.put(key, node);
setHead(node);
}
}
}
class Node{
int key;
int value;
Node prev;
Node next;
public Node(int key, int value){
this.key = key;
this.value = value;
prev = null;
next = null;
}
}
}