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.
用双向链表来存储实际的key,value。链表末尾位是最近最少访问的元素,链表头尾最近访问的元素 -----链表用来淘汰元素
用map来寻找元素,定位元素
之所以要用双向链表是为了方便删除节点,时间复杂度为O(1),单向链表删除节点要遍历找到前一个节点才能删除后一个节点-时间复杂度为O(n)
class LRUCache{
public:
LRUCache(int capacity) {
capacity_=capacity;
}
int get(int key) {
if(map_.count(key)==0)
return -1;
list< pair<int,int> >::iterator it= map_[key];
int value = it->second;
//移动到最前面
list_.erase(it) ;
list_.push_front( pair<int,int>(key,value) ) ;
//更新map
map_[key] = list_.begin() ;
return value;
}
void set(int key, int value) {
if(map_.count(key)!=0) //已经有了
{
list< pair<int,int> >::iterator it= map_[key];
//移动到最前面
list_.erase(it) ;
list_.push_front(pair<int,int>(key,value)) ;
//更新map
map_[key] = list_.begin() ;
}
else
{
//满了先删除
if( map_.size() == capacity_ )
{
map_.erase( list_.back().first );//back() 返回最后一个元素的引用 ,不是迭代器
list_.pop_back();
}
list_.push_front(pair<int,int>(key,value));
map_[key] = list_.begin();
}
}
private:
unordered_map<int, list< pair<int,int> >::iterator > map_;
//当缓存满了的时候,要移除list的最后一个,同时还要移除map中对应的那个,所以list要保存list到map的映射关系key,不能只保存value
list< pair<int,int> > list_;
int capacity_;
};