您的位置:首页 > 其它

[LeetCode] LRU Cache

2013-11-21 01:40 369 查看
Question:
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.

解题思路:

LRU是Least Recently Used 的缩写,即“最不常使用”,也就是说,LRU缓存把最不常使用的数据移除,让给最新读取的数据。大多数情况下,最常读取的,也是读取次数最多的,所以,利用LRU缓存我们能够提高系统的performance。 LRU cache是非常频繁出现的一道面试题,一般来讲,当我们问到这道题时,面试官往往想得到的答案是利用 doubly linked list + map(即hashtable) 实现 LRU Cache, 下面我们就利用doubly linked list + map来实现LRU
Cache。

首先,这里使用Doubly linkd list 而不使用 Linked list的原因是:

当访问一个节点后,我们需要将他从原来的list中删除,然后将它插入到头节点处,删除过程中需要将其前后节点连接起来,单链表做不到。
查询:
(1)根据键值查询hashmap,若命中,则返回节点,否则返回null。

(2)从双向链表中删除命中的节点,将其重新插入到表头。

所有操作的复杂度均为O(1)。

插入:

(1)将新的节点关联到map

(2)如果Cache满了,删除双向链表的尾节点,同时删除map对应的记录

(3)将新的节点插入到双向链表中头部
更新:

和查询相似
删除:

从双向链表和map中同时删除对应的记录。

C++代码如下:

struct node
{
node* pre;
int key;
int value;
node* next;
node(int k, int v):key(k),value(v),pre(NULL),next(NULL) {};
};

class LRUCache
{
map<int, node*> mp;
node* head;
node* tail;
int size;
int capacity;
public:
LRUCache(int c)
{
if (c < 1)return;
head = new node(0, 0);
tail = new node(0, 0);
head->next = tail;
tail->pre = head;
mp.clear();
size = 0;
capacity = c;
}

int get(int k)
{
map<int, node*>::iterator it = mp.find(k);
if (it != mp.end())
{
node* cur = (*it).second;
cur->pre->next = cur->next;
cur->next->pre = cur->pre;
putToHead(cur);
return cur->value;
}
else
return -1;
}

void set(int k, int val)
{
if (capacity < 1) return;
map<int, node*>::iterator it = mp.find(k);
if (it != mp.end()) //find
{
node* cur = (*it).second;
cur->pre->next = cur->next;
cur->next->pre = cur->pre;
cur->value = val;
putToHead(cur);
}
else //not find
{
node* tmp = new node(k,val);
putToHead(tmp);
mp[k] = tmp;
if (size < capacity) //size < capacity
{
size++;
}
else //size >= capacity
{
node* deltmp = tail->pre;
tail->pre = deltmp->pre;
deltmp->pre->next = tail;
it = mp.find(deltmp->key);
mp.erase(it);
delete deltmp; //Don't forget the delete operation;
}
}
}

void putToHead(node* cur)
{
cur->next = head->next;
cur->pre = head;
cur->next->pre = cur;
head->next = cur;
}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LRU cache