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_;
};