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:
Version 1:
public class LRUCache {
public LRUCache(int capacity) {
}
public int get(int key) {
}
public void set(int key, int value) {
}
}
public class Solution_134 {
private class Node{
int key;
int value;
Node prev;
Node next;
public Node(int key,int value){
this.key=key;
this.value=value;
this.next=null;
this.prev=null;
}
}
public int capacity;
public HashMap<Integer,Node> hm=new HashMap<Integer,Node>();//Integer is the key.hashmap is the cache
public Node head=new Node(-1,-1);
public Node tail=new Node(-1,-1);
public Solution_134(int capacity) {
this.capacity=capacity;
//caution: first connection the dummy head and dummy tail
tail.prev = head;
head.next = tail;
}
//Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
public int get(int key) {
if(!hm.containsKey(key)){
return -1;
}
Node current=hm.get(key);
removeCurrent(current);
moveTotail(current);
return hm.get(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 void set(int key, int value) {
if(get(key)!=-1)//this key is in the cache,change its value;
{
hm.get(key).value=value;
return;
}
else{
Node insert = new Node(key,value);
if(hm.size()>=capacity){
hm.remove(head.next.key);//remove it from hashmap
//remove from linkedlist
head.next=head.next.next;
head.next.prev=head;
}
hm.put(key, insert);//update the cache(hm)
moveTotail(insert);//put it in the newest
}
}
//when get a key that exist in the List then remove it from original position to tail
public void removeCurrent(Node n){
/*if(n.prev!=null){
n.prev.next=n.next;
}
else{
head=n.next;
}
if(n.next!=null){
n.next.prev=n.prev;
}
else{
tail=n.prev;
}*/
n.prev.next=n.next;
n.next.prev=n.prev;
}
//Move to tail
public void moveTotail(Node n){
n.prev=tail.prev;
tail.prev.next=n;
tail.prev=n;
n.next=tail;
}
}