146. LRU Cache
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(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.
Follow up:
Could you do both operations in O(1) time complexity?
Example:
LRUCache cache = new LRUCache( 2 /* capacity */ ); cache.put(1, 1); cache.put(2, 2); cache.get(1); // returns 1 cache.put(3, 3); // evicts key 2 cache.get(2); // returns -1 (not found) cache.put(4, 4); // evicts key 1 cache.get(1); // returns -1 (not found) cache.get(3); // returns 3 cache.get(4); // returns 4get操作时,需要执行下面两步操作:
1/返回map中key对应的value;
2/同时需要更新list中key的位置,将key放置在list中最近被访问的位置上,那么可以定义list中的首端(front)元素是最近被访问的元素。更新操作同样需要两部来完成:1:删除list中原来的key;2:将key插入list首端。
set操作会比较复杂一些:
1/首先判断要插入的key是否存在map中,如果存在的话,只需要更新map中对应的value,同时执行上面get中的第二步操作;
2/如果key不存在map中,那么需要判断map容量是否已满,如果满了,就需要从map中删除一个元素,这时list就派上用场了,因为最近使用的key位于list的首端,那么最久未使用的元素就位于list尾端,可以从list中取出最久未使用的key,同时删除map中对应的key和value。
3/然后将数据插入map和list中。
注意要点:
1、pair的用法 typedef pair<int, list<int>::iterator> PILI;
2、typedef的用法
3、iterator的用法。只要把一个元素的it存下来,之后就能用这个定位。和数组前面插入,后面的后移是不一样的。
4、map最后一个元素 s.back()
5、list是插入删除最快的STL,特点是可以两端插入删除。
class LRUCache {
public:
LRUCache(int capacity)
{
this->capacity = capacity;
}
int get(int key)
{
auto it = datas.find(key);
if( it != datas.end() )
{
update(it);
return it->second.first;
}
else
return -1;
}
void put(int key, int value)
{
int length = datas.size();
auto iter = datas.find(key);
if (iter != datas.end()) //如果找到了
{
iter->second.first = value;
update(iter);
}
else
{
if(length >= capacity)
{
datas.erase(s.back()); //把最后面那个key对应的map删除
s.pop_back(); //把list中的最后那个key删除
}
s.push_front(key);
datas[key] = PILI(value, s.begin()); //关键!
}
}
private:
typedef pair<int, list<int>::iterator> PILI; //第一位存 value,第二位 存 在list中的位置(迭代器)
map<int, PILI> datas; //存数据
int capacity;
list<int> s; //list存的是key值,但关键是迭代器的位置。 s.front()是最近的。 list的特点就是中间删除很快
void update(map<int, PILI>::iterator it) //更新map的这个迭代器
{
int key = it->first;
s.erase(it->second.second); //删除原本的位置
s.push_front(key); //移动到最前面去
it->second.second = s.begin(); //重新定位
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
本文介绍了一种使用C++实现的LRU缓存数据结构。该结构支持get和put操作,并能在O(1)时间内完成。文章详细解释了如何通过结合map和list来高效地管理缓存中的数据。
1233

被折叠的 条评论
为什么被折叠?



