题目:
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.
1)题目分析:set操作:当key存在时,执行修改操作。当key不存在时,执行插入操作,此时分为两种情况,一种是超过边界值时,需要删除最近最少使用的变量;另一种为未超过边界值时,直接执行插入操作。
get操作:获得某个值时,此时对给变量执行了一次操作。
2)解题思路:
a. 用一个链表存数据,数据为一个结构体。头指针指向最近使用,尾指针指向最久没使用的变量。
b. 用一个map存取key和当前key在链表中的指针地址。
c. 当执行set操作时,需要检查是否存在当前key,是执行插入操作,同时修改链表位置,将该项调整到头指针,同时修改map中对应的值。若不存在,则需判断是否超过边界,若超过,删除链表尾指针和map项,接着执行插入操作。
d. 执行get操作时,查找map,若找到,获得当前的链表地址,获得数据,同时,修改链表位置为当前头指针,同时修改map中的项。
class LRUCache
{
public:
LRUCache(int capacity)
{
m_capacity = capacity;
}
int get(int key)
{
map<int,list<cachenode>::iterator>::iterator pos;
pos = m_cachemap.find(key);
if (pos == m_cachemap.end())
{
return -1;
}
else
{
int ivalue = pos->second->value;
m_list.splice(m_list.begin(),m_list,pos->second);
//注意此时pos已经无效
pos = m_cachemap.find(key);
pos->second = m_list.begin();
return ivalue;
}
}
void set(int key, int value)
{
map<int,list<cachenode>::iterator>::iterator pos;
pos = m_cachemap.find(key);
if (pos != m_cachemap.end())
{
pos->second->value = value;
m_list.splice(m_list.begin(),m_list,pos->second);
return;
}
else
{
if (m_cachemap.size() == m_capacity)
{
cachenode icachenode = m_list.back();
m_list.pop_back();
pos = m_cachemap.find(icachenode.key);
m_cachemap.erase(pos);
cachenode cnode(key,value);
m_list.push_front(cnode);
m_cachemap.insert(make_pair(key,m_list.begin()));
}
else
{
cachenode cnode(key,value);
m_list.push_front(cnode);
m_cachemap.insert(make_pair(key,m_list.begin()));
}
}
}
private:
int m_capacity;
struct cachenode
{
int key;
int value;
cachenode(int ikey,int ivalue)
{
key = ikey;
value = ivalue;
}
};
list<cachenode>m_list;
map<int,list<cachenode>::iterator> m_cachemap;
};