LRU Cache
/**
* 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.
*/
public class LRUCache {
private HashMap<Integer, LRUCache.DoubleLinkedListNode> map = new HashMap<Integer, LRUCache.DoubleLinkedListNode>();
private DoubleLinkedListNode head;
private DoubleLinkedListNode end;
private int capacity;
private int len;
public LRUCache(int capacity) {
this.capacity = capacity;
this.len = 0;
}
public int get(int key) {
if(this.map.containsKey(key)){
// move this referred frame to the front;
removeNode(this.map.get(key));
setHead(this.map.get(key));
return this.map.get(key).val;
}else{
return -1;
}
}
public void set(int key, int value) {
if(this.map.containsKey(key)){
// if the map contains this frame, set the value, move it to the front.
DoubleLinkedListNode curr = this.map.get(key);
curr.val = value;
removeNode(curr);
setHead(curr);
}else{
// if the map doesn't contain this frame, insert it.
DoubleLinkedListNode curr = new DoubleLinkedListNode(key, value);
if(this.len < this.capacity){
setHead(curr);
this.map.put(key, curr);
this.len++;
}else{
this.map.remove(this.end.key);
this.end = this.end.pre;
if(this.end != null){
this.end.post = null;
}
setHead(curr);
this.map.put(key, curr);
}
}
}
private class DoubleLinkedListNode {
public int val;
public int key;
public DoubleLinkedListNode pre;
public DoubleLinkedListNode post;
// constuctor
public DoubleLinkedListNode(int key, int value){
this.val = value;
this.key = key;
}
}
private void setHead(DoubleLinkedListNode node){
node.post = this.head;
node.pre = null;
if(this.head != null){
this.head.pre = node;
}
this.head = node;
if(this.end == null){
this.end = node;
}
}
private void removeNode(DoubleLinkedListNode node){
DoubleLinkedListNode curr = node;
DoubleLinkedListNode pre = curr.pre;
DoubleLinkedListNode post = curr.post;
if(pre != null){
pre.post = post;
}else{
this.head = post;
}
if(post != null){
post.pre = pre;
}else{
this.end = pre;
}
}
}