题目
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,保存调度列表,map保存映射值。
关于set的实现:
<span style="font-size:14px;">if key in list
move key to the end of list
else
insert key at the end of list
insert (key, value) to map
if list.size > capacity
delete the front of the list
delete key in map</span>
这个算法看起来及实现起来都不难,使用map足以满足要求,在list尾部插入,list头部删除key的效率都为O(1),都不会影响效率。唯有当key存在时,move操作,需要从list找到此key的复杂度为O(n),采用删除操作,在尾部插入。这是一个唯一影响效率的地方。结果就是TLE。
怎样才能实现,根据一个key,快速定位到key在list中的位置呢?所以,这样可以构成一个映射,采用map,可以提高效率。
此思想参考了heiyanbin的代码:https://oj.leetcode.com/discuss/6647/my-o-1-solution 。
复杂度
对list复杂度不了解,暂不分析
注意
输入:set(2,1) set(2,2) get(2)
得到的结果应该是2,而不是1,所以只要是set必须更新value。
CODE
class LRUCache{
public:
LRUCache(int capacity) {
this->capacity = capacity;
}
int get(int key) {
auto it = mp.find(key);
if (it != mp.end()) {
movetoEnd(key);
return it->second;
} else {
return -1;
}
}
void set(int key, int value) {
auto it = mp.find(key);
if (it != mp.end()) {
mp[key] = value;
movetoEnd(key);
} else {
mp[key] = value;
l.push_back(key);
pos[key] = getLast();
if (l.size() > capacity) {
int moveKey = l.front();
l.pop_front();
mp.erase(moveKey);
pos.erase(moveKey);
}
}
}
void movetoEnd(int key) {
auto it = pos[key];
l.erase(it);
l.push_back(key);
pos[key] = getLast();
}
list<int>::iterator getLast() {
auto it = l.end();
return --it;
}
private:
list<int> l;
map<int, int> mp;
map<int, list<int>::iterator> pos;
int capacity;
};
306

被折叠的 条评论
为什么被折叠?



