146.LRU 缓存

LRU 缓存

请你设计并实现一个满足 LRU (最近最少使用) 缓存约束的数据结构。

实现 LRUCache 类:

  • LRUCache(int capacity)正整数 作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1
  • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value;如果不存在,则向缓存中插入该组 key-value。如果插入操作导致关键字数量超过 capacity,则应该逐出最久未使用的关键字。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

示例:

输入:
[“LRUCache”, “put”, “put”, “get”, “put”, “get”, “put”, “get”, “get”, “get”]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出:
[null, null, null, 1, null, -1, null, -1, 3, 4]

提示:

  • 1 <= capacity <= 3000
  • 0 <= key <= $10^4$
  • 0 <= value <= $10^5$
  • 最多调用 $2 * 10^5$ 次 get 和 put

解析

使用 Map 利用其插入顺序特性来实现 LRU。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* @param {number} capacity
*/
var LRUCache = function (capacity) {
this.capacity = capacity;
this.cache = new Map();
};

/**
* @param {number} key
* @return {number}
*/
LRUCache.prototype.get = function (key) {
if (!this.cache.has(key)) return -1;
const value = this.cache.get(key);
// 移到最新位置
this.cache.delete(key);
this.cache.set(key, value);
return value;
};

/**
* @param {number} key
* @param {number} value
* @return {void}
*/
LRUCache.prototype.put = function (key, value) {
if (this.cache.has(key)) {
this.cache.delete(key);
}
this.cache.set(key, value);
if (this.cache.size > this.capacity) {
// 删除最早插入的(最久未使用的)
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
};

JavaScript 的 Map 保持插入顺序,删除后重新 set 即可更新顺序,非常适合实现 LRU 缓存。get 和 put 均为 O(1)。


146.LRU 缓存
https://leetcode.lz5z.com/146.lru-cache/
作者
tickli
发布于
2024年4月29日
许可协议