From 6f7fef12cc3007f4dbd0b2f3c91ec18c06f67723 Mon Sep 17 00:00:00 2001 From: ShusenTang Date: Mon, 2 Mar 2020 23:27:01 +0800 Subject: [PATCH] add 146. LRU Cache :beer: --- README.md | 1 + solutions/146. LRU Cache.md | 59 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 solutions/146. LRU Cache.md diff --git a/README.md b/README.md index 90563e6..6917971 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ My LeetCode solutions with Chinese explanation. 我的LeetCode中文题解。 | 142 |[Linked List Cycle II](https://leetcode.com/problems/linked-list-cycle-ii/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/142.%20Linked%20List%20Cycle%20II.md)|Medium| | | 143 |[Reorder List](https://leetcode.com/problems/reorder-list/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/143.%20Reorder%20List.md)|Medium| | | 144 |[Binary Tree Preorder Traversal](https://leetcode.com/problems/binary-tree-preorder-traversal/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/144.%20Binary%20Tree%20Preorder%20Traversal.md)|Medium| | +| 146 |[LRU Cache](https://leetcode.com/problems/lru-cache/)|[C++](solutions/146.%20LRU%20Cache.md)|Medium| | | 148 |[Sort List](https://leetcode.com/problems/sort-list/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/148.%20Sort%20List.md)|Medium| | | 150 |[Evaluate Reverse Polish Notation](https://leetcode.com/problems/evaluate-reverse-polish-notation/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/150.%20Evaluate%20Reverse%20Polish%20Notation.md)|Medium| | | 151 |[Reverse Words in a String](https://leetcode.com/problems/reverse-words-in-a-string/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/151.%20Reverse%20Words%20in%20a%20String.md)|Medium| | diff --git a/solutions/146. LRU Cache.md b/solutions/146. LRU Cache.md new file mode 100644 index 0000000..989d739 --- /dev/null +++ b/solutions/146. LRU Cache.md @@ -0,0 +1,59 @@ +# [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(); + } + } +}; +```