地址:http://oj.leetcode.com/problems/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.
用list来存取hash表里各个key的前后关系,不维护value,若是取value的值则从hash表里取,位置越靠前则越是最近使用到(get或者set过)。
list_it_map的value是key在list中的指针(c++迭代器)
笔者觉得这题难点有两个,一个是C++中list与unordered_map的操作,二个是基于上述操作的逻辑。
第二份代码用的vector与unordered_map来操作,逻辑上可以简化很多,但是TLE了。
参考代码 AC:
class LRUCache{
private:
list<int>lrulist;
unordered_map<int, int>dm;
unordered_map<int, list<int>::iterator>list_it_map;
unordered_map<int, int>::iterator dmit;
unordered_map<int, list<int>::iterator>::iterator mapit;
int capacity;
public:
LRUCache(int capacity) {
lrulist.clear();
dm.clear();
this->capacity = capacity;
}
int get(int key) {
dmit = dm.find(key);
mapit = list_it_map.find(key);
if(dmit!=dm.end())
{
lrulist.splice(lrulist.begin(), lrulist, mapit->second);
return dmit->second;
}
return -1;
}
void set(int key, int value) {
dmit = dm.find(key);
mapit = list_it_map.find(key);
if(dmit == dm.end())
{
if(lrulist.size()==capacity)
{
dmit = dm.find(lrulist.back());
dm.erase(dmit);
mapit = list_it_map.find(lrulist.back());
list_it_map.erase(mapit);
lrulist.pop_back();
}
dm[key] = value;
lrulist.push_front(key);
list_it_map[key] = lrulist.begin();
}
else
{
dm[key] = value;
lrulist.splice(lrulist.begin(), lrulist, mapit->second);
}
}
};
用vector代码:教容易理解,但是 TLE
class LRUCache{
private:
struct node{
int key, val, index;
};
vector<node>vec;
unordered_map<int, int>dm;
int capacity;
node n;
public:
LRUCache(int capacity) {
vec.clear();
dm.clear();
this->capacity = capacity;
}
int get(int key) {
auto it = dm.find(key);
if(it!=dm.end())
return it->second;
return -1;
}
void set(int key, int value) {
if(dm.find(key) == dm.end())
{
if(vec.size()==this->capacity)
{
for(int i = 0; i<vec.size(); ++i)
{
if(vec[i].index == vec.size()-1)
{
auto iter = dm.find(vec[i].key);
dm.erase(iter);
dm.insert(pair<int, int>(key, value));
vec[i].key = key;
vec[i].val = value;
vec[i].index = 0;
}
else
++vec[i].index;
}
}
else
{
dm[key] = value;
n.key = key;
n.val = value;
n.index = vec.size();
vec.push_back(n);
}
}
else
{
dm[key] = value;
for(int i = 0; i<vec.size(); ++i)
{
if(vec[i].key == key)
vec[i].index = 0;
else
++vec[i].index;
}
}
}
};