Algorithms first
LRU 缓存 · 交互式算法学习
设计 O(1) get/put 的最近最少使用缓存。
#146 · 链表
LRU 缓存
LRU Cache
capacity = 2; put(1,1), put(2,2), get(1), put(3,3)栈 / 队列 / 堆3 个关键状态
步骤 1哈希表定位 1、2,链表记录顺序。
1↔2队首
1:1
2:2
get 1
3:3
队尾
推荐
哈希表 + 双向链表
时间
所有操作 O(1)空间 O(capacity)哈希表定位节点;双向链表 O(1) 移动、插入和淘汰尾部。
1class LRUCache {2 constructor(c) {3 this.c = c;4 this.m = new Map()5 }6 get(k) {7 if (!this.m.has(k)) return -1;8 const v = this.m.get(k);9 this.m.delete(k);10 this.m.set(k, v);11 return v12 }13 put(k, v) {14 this.m.delete(k);15 this.m.set(k, v);16 if (this.m.size > this.c) this.m.delete(this.m.keys().next().value)17 }18}多语言参考
来源 · CC BY-SA 4.0 ↗Java · C++ · Go
这是一组同题正确实现,独立于上方当前动画方法;不同语言可能采用另一种正确策略。
1class Node {2 int key, val;3 Node prev, next;4 5 Node() {6 }7 8 Node(int key, int val) {9 this.key = key;10 this.val = val;11 }12}13 14class LRUCache {15 private int size;16 private int capacity;17 private Node head = new Node();18 private Node tail = new Node();19 private Map<Integer, Node> cache = new HashMap<>();20 21 public LRUCache(int capacity) {22 this.capacity = capacity;23 head.next = tail;24 tail.prev = head;25 }26 27 public int get(int key) {28 if (!cache.containsKey(key)) {29 return -1;30 }31 Node node = cache.get(key);32 removeNode(node);33 addToHead(node);34 return node.val;35 }36 37 public void put(int key, int value) {38 if (cache.containsKey(key)) {39 Node node = cache.get(key);40 removeNode(node);41 node.val = value;42 addToHead(node);43 } else {44 Node node = new Node(key, value);45 cache.put(key, node);46 addToHead(node);47 if (++size > capacity) {48 node = tail.prev;49 cache.remove(node.key);50 removeNode(node);51 --size;52 }53 }54 }55 56 private void removeNode(Node node) {57 node.prev.next = node.next;58 node.next.prev = node.prev;59 }60 61 private void addToHead(Node node) {62 node.next = head.next;63 node.prev = head;64 head.next = node;65 node.next.prev = node;66 }67}68 69/**70 * Your LRUCache object will be instantiated and called as such:71 * LRUCache obj = new LRUCache(capacity);72 * int param_1 = obj.get(key);73 * obj.put(key,value);74 */交互式算法学习
从执行步骤真正理解 LeetCode 经典 150
本站整理 150 道高频算法面试题和 302 种解法。动画方法同步展示 JavaScript 与 Python;每题另提供 Java、C++ 与 Go 同题参考实现。
AlgoViz Lab
LRU 缓存 · 解法对比
设计 O(1) get/put 的最近最少使用缓存。
- 测试用例
capacity = 2; put(1,1), put(2,2), get(1), put(3,3)- 题目分类
- 链表
- 解法对比
- 2
数组维护使用顺序
数组按新旧顺序存键;访问时线性定位并移动到末尾。
- 时间
get/put O(n)- 空间
O(capacity)
哈希表 + 双向链表
哈希表定位节点;双向链表 O(1) 移动、插入和淘汰尾部。
- 时间
所有操作 O(1)- 空间
O(capacity)