🧩Algo 链表
146. LRU 缓存
难度:🟡 Medium | 标签:哈希、双向链表、设计 | 状态:⬜ LeetCode 链接
思路
哈希 + 双向链表:
- 双向链表按访问时序:最近用过的在头,最久未用的在尾
- 哈希
key → 链表节点*,O(1) 定位
操作:
get:哈希查节点,命中则搬到头put:已存在则改值 + 搬到头;不存在则插头;超容则删尾
代码
class LRUCache {
struct Node { int k, v; Node *prev, *next; };
int cap;
Node head, tail; // dummy head & tail
unordered_map<int, Node*> mp;
void remove(Node* x) { x->prev->next = x->next; x->next->prev = x->prev; }
void addFront(Node* x) {
x->next = head.next; x->prev = &head;
head.next->prev = x; head.next = x;
}
public:
LRUCache(int capacity) : cap(capacity) {
head.next = &tail; tail.prev = &head;
}
int get(int key) {
auto it = mp.find(key);
if (it == mp.end()) return -1;
remove(it->second); addFront(it->second);
return it->second->v;
}
void put(int key, int value) {
auto it = mp.find(key);
if (it != mp.end()) {
it->second->v = value;
remove(it->second); addFront(it->second);
return;
}
if ((int)mp.size() == cap) {
Node* lru = tail.prev;
remove(lru); mp.erase(lru->k); delete lru;
}
Node* x = new Node{key, value, nullptr, nullptr};
addFront(x); mp[key] = x;
}
};
复杂度
- 时间 O(1) 单次操作
- 空间 O(capacity)
易错 / 回顾
- dummy head / tail 简化边界判断
- put 时已存在记得搬到头
- C++ 也可用
std::list+unordered_map<int, list<>::iterator>,代码更短 - LFU 是另一道题(460),结构更复杂
Related · 链表