题目:
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.
主题思路:
使用链表保存数据,每次get()或者set()时,将对应的数据结点移到链表头部,以表示该数据是最近一次被访问的数据。为了更快速查找key对应的数据是否存在以及所在位置,每次插入新的数据结点时,使用map建立key与list迭代器的映射.
C++代码实现:
class LRUCache{
public:
LRUCache(int cap):
capacity_(cap)
{
}
int get(int key) {
map_iterator it = cache_map_.find(key);
if (it == cache_map_.end() || 0 == capacity_) {
return -1;
} else {
// 将访问的结点移到链表头部
cache_list_.splice(cache_list_.begin(), cache_list_, it->second);
return cache_list_.begin()->value;
}
}
void set(int key, int value) {
map_iterator it = cache_map_.find(key);
if (it != cache_map_.end()) { // 如果结点已经存在
// 将访问的结点移到链表头部
// 然后更新value
cache_list_.splice(cache_list_.begin(), cache_list_, it->second);
cache_list_.begin()->value = value;
} else { // 否则新建插入
// 容量已满,移除末节点
if (cache_list_.size() == capacity_) {
cache_map_.erase(cache_list_.back().key);
cache_list_.erase(--cache_list_.end());
}
// 插入新的结点
cache_list_.push_front(ListNode(key,value));
cache_map_[key] = cache_list_.begin();
}
}
private:
struct ListNode {
int key;
int value;
ListNode(int _key, int _value): key(_key), value(_value) {
}
};
typedef list<ListNode>::iterator list_iterator;
typedef map<int, list_iterator>::iterator map_iterator;
int capacity_;
list<ListNode> cache_list_;
map<int, list_iterator> cache_map_;
};