[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:
key exists in the cache, otherwise return -1.
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;
}
};
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations:
getand
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;
}
};
相关文章推荐
- 《leetcode》: LRU Cache
- 【leetcode】LRU Cache
- 【LeetCode】LRU Cache
- Leetcode: LRU Cache
- leetcode之LRU Cache
- 【Leetcode】LRU Cache
- leetcode 146: LRU Cache
- [LeetCode] LRU Cache
- [leetcode] LRU Cache
- leetcode[146]LRU Cache
- leetcode 之LRU Cache(26)
- Leetcode: LRU Cache
- LRU Cache--LeetCode
- LeetCode: LRU Cache
- LeetCode:146_LRU cache | LRU缓存设计 | Hard
- [LeetCode#146]LRU Cache
- LeetCode ---LRU Cache
- 【LeetCode】LRU Cache
- [Leetcode] LRU Cache (Java)
- LeetCode 解题报告 LRU Cache