@@ -6,13 +6,12 @@ Tag : 「设计」、「链表」、「哈希表」
66
77
88
9+ 运用你所掌握的数据结构,设计和实现一个 ` LRU ` (最近最少使用) 缓存机制 。
10+ 实现 ` LRUCache ` 类:
911
10- 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
11- 实现 LRUCache 类:
12- 13- * LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
14- * int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
15- * void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
12+ * ` LRUCache(int capacity) ` 以正整数作为容量 ` capacity ` 初始化 ` LRU ` 缓存
13+ * ` int get(int key) ` 如果关键字 ` key ` 存在于缓存中,则返回关键字的值,否则返回 $-1$
14+ * ` void put(int key, int value) ` 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
1615
1716进阶:你是否可以在 $O(1)$ 时间复杂度内完成这两种操作?
1817
@@ -38,10 +37,10 @@ lRUCache.get(4); // 返回 4
3837```
3938
4039提示:
41- * 1 <= capacity <= 3000
42- * 0 <= key <= 3000
43- * 0 <= value <= $ 10^4$
44- * 最多调用 3 * $ 10^4$ 次 get 和 put
40+ * $ 1 <= capacity <= 3000$
41+ * $ 0 <= key <= 3000$
42+ * $ 0 <= value <= 10^4$
43+ * 最多调用 $ 3 * 10^4$ 次 ` get ` 和 ` put `
4544
4645---
4746
@@ -53,7 +52,7 @@ LRU 是一种十分常见的页面置换算法。
5352
5453** 题目让我们实现一个容量固定的 ` LRUCache ` 。如果插入数据时,发现容器已满时,则先按照 LRU 规则淘汰一个数据,再将新数据插入,其中「插入」和「查询」都算作一次"使用"。**
5554
56- 可以通过 🌰 来理解,假设我们有容量为 2ドル$ 的 ` LRUCache ` 和 测试键值对 ` [ ` 1-1` , ` 2-2` , ` 3-3` ] ` ,将其按照顺序进行插入 & 查询:
55+ 可以通过 🌰 来理解,假设我们有容量为 2ドル$ 的 ` LRUCache ` 和 测试键值对 ` [1-1, 2-2, 3-3] ` ,将其按照顺序进行插入 & 查询:
5756* 插入 ` 1-1 ` ,此时最新的使用数据为 ` 1-1 `
5857* 插入 ` 2-2 ` ,此时最新使用数据变为 ` 2-2 `
5958* 查询 ` 1-1 ` ,此时最新使用数据为 ` 1-1 `
@@ -74,15 +73,16 @@ LRU 是一种十分常见的页面置换算法。
7473具体的,我们使用哈希表来存储「键值对」,键值对的键作为哈希表的 Key,而哈希表的 Value 则使用我们自己封装的 ` Node ` 类,` Node ` 同时作为双向链表的节点。
7574
7675* 插入:检查当前键值对是否已经存在于哈希表:
77- * 如果存在,则更新键值对,并将当前键值对所对应的 ` Node ` 节点调整到链表头部(` refresh ` 操作)
78- * 如果不存在,则检查哈希表容量是否已经达到容量:
79- * 没达到容量:插入哈希表,并将当前键值对所对应的 ` Node ` 节点调整到链表头部(` refresh ` 操作)
80- * 已达到容量:先从链表尾部找到待删除元素进行删除(` delete ` 操作),然后再插入哈希表,并将当前键值对所对应的 ` Node ` 节点调整到链表头部(` refresh ` 操作)
81- * 查询:如果没在哈希表中找到该 Key,直接返回 $-1$;如果存在该 Key,则将对应的值返回,并将当前键值对所对应的 ` Node ` 节点调整到链表头部(` refresh ` 操作)
76+ 77+ * 如果存在,则更新键值对,并将当前键值对所对应的 `Node` 节点调整到链表头部(`refresh` 操作)
78+ 79+ * 如果不存在,则检查哈希表容量是否已经达到容量:
80+ * 没达到容量:插入哈希表,并将当前键值对所对应的 `Node` 节点调整到链表头部(`refresh` 操作)
81+ * 已达到容量:先从链表尾部找到待删除元素进行删除(`delete` 操作),然后再插入哈希表,并将当前键值对所对应的 `Node` 节点调整到链表头部(`refresh` 操作)
8282
83- 一些细节:
83+ * 查询:如果没在哈希表中找到该 Key,直接返回 $-1$;如果存在该 Key,则将对应的值返回,并将当前键值对所对应的 ` Node ` 节点调整到链表头部( ` refresh ` 操作)
8484
85- * 为了减少双向链表左右节点的「判空」操作,我们预先建立两个「哨兵」节点 ` head ` 和 ` tail ` 。
85+ 一些细节: 为了减少双向链表左右节点的「判空」操作,我们预先建立两个「哨兵」节点 ` head ` 和 ` tail ` 。
8686
8787代码:
8888``` Java []
@@ -162,7 +162,7 @@ class LRUCache {
162162
163163### 最后
164164
165- 这是我们「刷穿 LeetCode」系列文章的第 ` No.146 ` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先将所有不带锁的题目刷完 。
165+ 这是我们「刷穿 LeetCode」系列文章的第 ` No.146 ` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完 。
166166
167167在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
168168
0 commit comments