# [146. LRU Cache](https://leetcode.com/problems/lru-cache/) # 思路 题目要求设计一个最近最少使用(Least Recently Used, LRU)缓存。要求查询和插入都是O(1),如果插入后容量超过最大容量则需要删除最近最少使用的一个,即删除元素也需O(1)。 由于时间复杂度限制为O(1),所以肯定是要用hash,又因为我们需要删掉一个最不常用的元素,所以我们需要维护一个按照最近使用过的先后顺序的序列,这个序列要能在O(1)的时间复杂度在头部进行插入和在尾部进行删除,所以可以使用双向环形链表,即STL中的`list`。 综上,所以我们维护一个hashmap,存放key到list的迭代器的映射;还要维护一个存放value的`list`,其中的元素是一个pair(key, value)。 * `get`:在hashmap中查找对应list的迭代器,如果找到则需要将该元素移动到list头部(可以先删除再在头部插入或者直接使用STL中的`splice`); * `put`:现在hashmap中查找,如果找到了需要先删除原来的;再在list头部插入;最后检测是否超过最大容量,若是需要删除list尾部对应元素。 注意: * 环形双向链表`list`的用法,如`push_front`、`pop_back`等。 * `rbegin()`返回容器最后一个元素的迭代器。 * `l.splice (iterator position, list& x, iterator i)`可以将list x的元素 i 插入到容器的position位置。 # C++ ``` C++ class LRUCache { private: int cap; list>values; // unordered_map>::iterator>cache; public: LRUCache(int capacity): cap(capacity){ } // 列表初始化 int get(int key) { auto cache_iter = cache.find(key); if(cache_iter == cache.end()) return -1; else { auto value_iter = cache_iter -> second; int value = value_iter -> second; // values.splice(values.begin(), values, value_iter); // 也可以用下面三行代码 values.erase(value_iter); values.push_front({key, value}); cache[key] = values.begin(); return value; } } void put(int key, int value) { auto cache_iter = cache.find(key); if(cache_iter != cache.end()) values.erase(cache_iter -> second); values.push_front({key, value}); cache[key] = values.begin(); if(values.size() > cap){ cache.erase(values.rbegin() -> first); values.pop_back(); } } }; ```