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(); } } };