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.
import java.util.HashMap;
import java.util.LinkedList;
class ListNode{
int key, value;
ListNode next, prev;
public ListNode()
{
this.key = this.value = 0;
next = prev = null;
}
public ListNode(int key, int val)
{
this.key = key;
this.value = val;
next = prev = null;
}
}
public class LRUCache {
private ListNode head,tail;
private HashMap<Integer, ListNode> hashmap;
private int size, capacity;
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public LRUCache(int capacity) {
this.size = 0;
this.capacity = capacity;
head = new ListNode();
tail = new ListNode();
head.next = tail;
tail.prev = head;
hashmap = new HashMap<Integer, ListNode>();
}
public int get(int key) {
if (hashmap.containsKey(key)) {
ListNode cur = hashmap.get(key);
//detach the node in the list
cur.prev.next = cur.next;
cur.next.prev = cur.prev;
//set the visting node be the firstNode.
ListNode tmp = head.next;
head.next = cur;
cur.prev = head;
cur.next = tmp;
tmp.prev = cur;
return cur.value;
}
else return -1;
}
public void set(int key, int value) {
if (hashmap.containsKey(key)) {
ListNode cur = hashmap.get(key);
cur.value = value;
//detach
cur.prev.next = cur.next;
cur.next.prev = cur.prev;
//set the visting node be the firstNode.
ListNode tmp = head.next;
head.next = cur;
cur.prev = head;
cur.next = tmp;
tmp.prev = cur;
}
else {
if (size == capacity) {
ListNode last = tail.prev;
hashmap.remove(last.key);
tail = last;
last = null;
size--;
}
ListNode cur = new ListNode(key, value);
hashmap.put(key, cur);
//set the new node be the firstNode.
ListNode tmp = head.next;
head.next = cur;
cur.prev = head;
cur.next = tmp;
tmp.prev = cur;
size++;
}
}
}