LRU算法思想,可粗略参考这篇文章:传送门。
首先定义节点:
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
至于要实现这个题目的要求,就这样解决:利用list来实现一个特殊的“栈”,这个“栈”中的元素每当被访问就被提到栈顶(即该list第一个位置,利用list函数splice实现),每当“栈”满,适逢要加入新元素,则移除“栈”底元素。
为了实现对该list实现的栈的随机访问,维护一个unordered_map(基于hash实现),键-值为<key, list::iterator>对,这样可以在时间复杂度O(1)内获得指定key的元素的iterator。当元素从栈底(即list::back())被移除时,同时移除map中对应项。当元素在被访问后被提前到“栈顶”,同样更新map中对应键值的元素的iterator.
本题实现细节参考了这位仁兄:传送门,不敢掠美,共同学习。
class LRUCache{
private:
list<Node> s;
unordered_map<int, list<Node>::iterator> addr;
int size;
public:
LRUCache(int capacity) :size(capacity){ }
int get(int key) {
if (addr.find(key) == addr.end())
return -1;
s.splice(s.begin(), s, addr[key]);
addr[key] = s.begin();
return addr[key]->value;
}
void set(int key, int value) {
Node* target = NULL;
if ( addr.find(key)!= addr.end())
{
addr[key]->value = value;
s.splice(s.begin(), s, addr[key]);
addr[key] = s.begin();
}
else{
if (s.size() == size)
{
addr.erase(s.back().key);
s.pop_back();
}
s.push_front(Node(key,value));
addr[key] = s.begin();
}
}
};