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.
這道題是Amazon將要考的coding題。
先開始想的方法是用Queue, 之後想的方法是double linked List, 可以實現O(1)的delete,add 操作。再加上HashTable來解決查找問題
這樣set和get的time complexity 是O(1), space complexity 是O(1)
public class LRUCache {
HashMap<Integer, ListNode> map;
LinkedList list;
int numOfItems;
int capacity;
public LRUCache(int capacity){
this.capacity = capacity;
map = new HashMap<Integer, ListNode>();
list = new LinkedList()
}
public int get(int key){
//loop all the priority queue and find if the key is in the priority queue
if(map.containsKey(key)){
ListNode tem = map.get(key);
delete(tem);
add(tem);
return tem.val;
}
else{
System.out.print("there is no such key in the linkedList")
return Integer.MAX_VALUE;
}
}
public void set(int key, int value) {
//deal with the corner condition that the number of the items equal to 0
if(capacity <= 0)
return;
//The condition that the number of the items is less than the capacity
if(map.containsKey(key)){
ListNode tem = map.get(key);
ListNode newOne = new ListNode(value);
list.delte(tem);
list.add(newOne);
map.add(key. newOne);
}
else{
if(numOfItems < capacity){
ListNode tem = new ListNode(value)
map.add(key, tem);
numOfItems++;
}
else{
ListNode toBeDeleted = list.tail.pre;
list.delete();
map.remove(toBeDeleted.key);
ListNode newOne = new ListNode(value);
list.add(newOne);
map.add(key. newOne);
}
}
}
public class ListNode{
int val;
ListNode pre;
ListNode next;
public ListNode(int val){
this.val = val;
}
public ListNode(int val, ListNode pre, ListNode next){
this.val = val;
this.pre = pre;
this.next = next;
}
}
public class LinkedList{
ListNode head;
ListNode tail;
HashMap<Integer,Integer> map;
public LinkedList(){
head = new ListNode(0);
tail = new ListNode(0);
// tail = head;
//This is to build the cache for the list
head.next = tail;
tail.pre = head;
map = new HashMap<Integer,Integer>();
}
//This method is to add the val to the head of the linkedList
public void add(int val){
ListNode curr = new ListNode(val);
curr.next = head.next;
head.next.pre = curr;
curr.pre = head;
head.next = curr;
// if(tail == head))
// tail = curr;
}
//this method is to add the list node to the head of the linkedList
public void add(ListNode curr){
curr.next = head.next;
head.next.pre = curr;
curr.pre = head;
head.next = curr;
}
//the method is to delete the least used process from the cache
public void delete(){
//first judge if the pre node of tail is the head node
if(tail.pre == head)
return;
tail.pre = tail.pre.pre;
tail.pre.next = tail;
}
//this is to just to delete the node O(1)
public void delete(ListNode tem){
tem.pre.next = tem.next;
tem.next.pre = tem.pre;
}
}
}