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.
Java:
http://blog.csdn.net/linhuanmars/article/details/21310633
基本思路是这样的,用一个hash表来维护结点的位置关系,也就是hash表的key就是资源本身的key,value是资源的结点(包含key和value的信息)。然后把结点维护成一个双向链表构成的队列,这样子如果我们要访问某一个结点,那么可以通过hash表和key来找到结点,从而取到相应的value。而当我们想要删除或者插入结点时,我们还是通过hash表找到结点,然后通过双向链表和队列的尾结点把自己删除同时插入到队尾。
这道题是一道很实际的题目,思路和数据结构都是很适合面试的题目,但是代码量有些偏大,所以一般只在onsite的时候有可能遇到,可能也不会让你完整地写出全部代码,主要还是讲出维护的数据结构和各种操作复杂度的分析。
public class LRUCache {
class Node{
Node pre, next;
int key;
int val;
public Node(int key, int value)
{
this.key=key;
this.val=value;
}
}
private int capacity;
private int num;
private HashMap<Integer,Node> map;
private Node first, last;
public LRUCache(int capacity) {
this.capacity=capacity;
num=0;
map=new HashMap<Integer,Node>();
first=null;
last=null;
}
public int get(int key) {
Node node=map.get(key);
if(node==null) return -1;
else if(node!=last)
{
if(node==first)
{
first=first.next;
}
else node.pre.next=node.next;
node.next.pre=node.pre;
last.next=node;
node.pre=last;
node.next=null;
last=node;
}
return node.val;
}
public void set(int key, int value) {
Node node=map.get(key);
if(node!=null)
{
node.val=value;
if(node!=last)
{
if(node==first)
{
first=first.next;
}
else node.pre.next=node.next;
node.next.pre=node.pre;
last.next=node;
node.pre=last;
node.next=null;
last=node;
}
}
else{
Node newNode = new Node(key,value);
if(num>=capacity)
{
map.remove(first.key);
first=first.next;
if(first!=null)
{
first.pre=null;
}
else{
last=null;
}
num--;
}
if(first==null||last==null)
{
first=newNode;
}
else{
last.next=newNode;
}
newNode.pre=last;
last=newNode;
map.put(key,newNode);
num++;
}
}
}