|
| 1 | +# 0146. LRU Cache |
| 2 | + |
| 3 | +**<font color=red>难度: Medium</font>** |
| 4 | + |
| 5 | +## 刷题内容 |
| 6 | + |
| 7 | +> 原题链接 |
| 8 | +
|
| 9 | +* https://leetcode.com/problems/lru-cache/ |
| 10 | + |
| 11 | +> 内容描述 |
| 12 | +
|
| 13 | +Design and implement a data structure for [Least Recently Used (LRU) cache](https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU). It should support the following operations: `get` and `put`. |
| 14 | + |
| 15 | +`get(key)` - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. |
| 16 | +`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. |
| 17 | + |
| 18 | +The cache is initialized with a **positive** capacity. |
| 19 | + |
| 20 | +**Follow up:** |
| 21 | +Could you do both operations in **O(1)** time complexity? |
| 22 | + |
| 23 | +**Example:** |
| 24 | + |
| 25 | +``` |
| 26 | +LRUCache cache = new LRUCache( 2 /* capacity */ ); |
| 27 | +
|
| 28 | +cache.put(1, 1); |
| 29 | +cache.put(2, 2); |
| 30 | +cache.get(1); // returns 1 |
| 31 | +cache.put(3, 3); // evicts key 2 |
| 32 | +cache.get(2); // returns -1 (not found) |
| 33 | +cache.put(4, 4); // evicts key 1 |
| 34 | +cache.get(1); // returns -1 (not found) |
| 35 | +cache.get(3); // returns 3 |
| 36 | +cache.get(4); // returns 4 |
| 37 | +``` |
| 38 | + |
| 39 | + |
| 40 | + |
| 41 | +## 解题方案 |
| 42 | + |
| 43 | +> 思路1 |
| 44 | +
|
| 45 | +******- 时间复杂度: O(1)******- 空间复杂度: O(N)****** |
| 46 | + |
| 47 | +这是一道数据结构的考题。 |
| 48 | + |
| 49 | +简单的获取和插入,顺序不做考虑,所以数据结构用Object即可。 |
| 50 | + |
| 51 | +但是重要的考点——[LRU](https://baike.baidu.com/item/LRU/1269842?fr=aladdin),也就是删除最近没有使用的数据。所以想到用`队列`存在key列表: |
| 52 | + |
| 53 | +* 未超过存储上限时,每次`put`一个新数据时,向队列末尾插入当前`key` |
| 54 | +* 每次`get`时,如果key存在,则将对应的key从的队列中,移到对末尾 |
| 55 | +* 在超过存储上限时,如进行`put`操作,则将队列首位删除掉 |
| 56 | + |
| 57 | +> 执行用时 :492 ms, 在所有 JavaScript 提交中击败了35.29%的用户 |
| 58 | +> |
| 59 | +> 内存消耗 :59.7 MB, 在所有 JavaScript 提交中击败了16.36%的用户 |
| 60 | +
|
| 61 | +```javascript |
| 62 | +/** |
| 63 | + * @param {number} capacity |
| 64 | + */ |
| 65 | +var LRUCache = function(capacity) { |
| 66 | + this.limit = capacity || 2 |
| 67 | + this.storage = {} |
| 68 | + this.keyList = [] |
| 69 | +}; |
| 70 | + |
| 71 | +/** |
| 72 | + * @param {number} key |
| 73 | + * @return {number} |
| 74 | + */ |
| 75 | +LRUCache.prototype.get = function(key) { |
| 76 | + if (this.storage.hasOwnProperty(key)) { |
| 77 | + let index = this.keyList.findIndex(k => k === key) |
| 78 | + this.keyList.splice(index, 1) |
| 79 | + this.keyList.push(key) |
| 80 | + return this.storage[key] |
| 81 | + } else { |
| 82 | + return -1 |
| 83 | + } |
| 84 | +}; |
| 85 | + |
| 86 | +/** |
| 87 | + * @param {number} key |
| 88 | + * @param {number} value |
| 89 | + * @return {void} |
| 90 | + */ |
| 91 | +LRUCache.prototype.put = function(key, value) { |
| 92 | + // 判断容量 |
| 93 | + if (this.keyList.length >= this.limit && !this.storage.hasOwnProperty(key)) { |
| 94 | + this.deleteLRU() |
| 95 | + } |
| 96 | + |
| 97 | + // 存储数据 |
| 98 | + this.updateKeyList(key) |
| 99 | + this.storage[key] = value |
| 100 | +}; |
| 101 | + |
| 102 | +LRUCache.prototype.deleteLRU = function () { |
| 103 | + delete this.storage[this.keyList.shift()] |
| 104 | +} |
| 105 | + |
| 106 | +LRUCache.prototype.updateKeyList = function (key) { |
| 107 | + if (this.storage.hasOwnProperty(key)) { |
| 108 | + var index = this.keyList.findIndex(k => key === k) |
| 109 | + this.keyList.splice(index, 1) |
| 110 | + } |
| 111 | + this.keyList.push(key) |
| 112 | +} |
| 113 | + |
| 114 | +/** |
| 115 | + * Your LRUCache object will be instantiated and called as such: |
| 116 | + * var obj = new LRUCache(capacity) |
| 117 | + * var param_1 = obj.get(key) |
| 118 | + * obj.put(key,value) |
| 119 | + */ |
| 120 | + |
| 121 | + |
| 122 | +``` |
| 123 | + |
| 124 | + |
| 125 | + |
0 commit comments