LeetCode LRU Cache
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.
解题思路:哈希表+链表。用哈希表保存key和value的映射,链表保存访问的cache序列,哈希表用map(或者unsorted_map)实现,每个key对应的value是节点在链表的迭代器;这样,每当访问某个key,就把其设置成链表的队尾,即:队尾就是最近访问的节点,队首就是最远访问的节点。
class LRUCache{
struct node
{
int key, val;
node(int k, int v)
{
key = k;
val = v;
}
};
typedef list<node> List;
//map的value是链表节点的迭代器
typedef map<int, List::iterator> Map;
int m_capacity;
List m_list;
Map m_map;
public:
//更新链表访问序列,把it移到队列末尾(在队尾生成一个和it一样的节点,再删除原来的节点)
List::iterator update(List::iterator it)
{
List::iterator new_it = m_list.insert(m_list.end(), *it);
m_list.erase(it);
return new_it;
}
LRUCache(int capacity) {
m_capacity = capacity;
}
int get(int key) {
Map::iterator it = m_map.find(key);
if (it == m_map.end())
return -1;
//更新访问序列
m_map[key] = update(it->second);
return m_map[key]->val;
}
void set(int key, int value) {
Map::iterator it = m_map.find(key);
if (it != m_map.end())
{
m_map[key] = update(it->second);
m_map[key]->val = value;
}
else
{
if (m_list.size() < m_capacity)
{
m_map[key] = m_list.insert(m_list.end(), node(key, value));
}
else
{
m_map.erase(m_list.front().key);
//删除最久未使用的节点,插入新节点
m_list.pop_front();
m_map[key] = m_list.insert(m_list.end(), node(key, value));
}
}
}
};