题目:146. LRU 缓存解题思路
思路步骤 代码
题目:146. LRU 缓存146. 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]解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4
提示:
1 <= capacity <= 30000 <= key <= 100000 <= value <= 105最多调用2 * 10^5次 get和 put 解题思路 思路
由于要求以O(1)时间,所以可以构造双链表可以以节点在链表中的位置来表示最近是否使用过
当get与put时,将节点取出,重新插入。put时删除最后一个节点 步骤
- 构造数据结构,包含key和value,左右节点。构造删除插入函数。初始化函数,包括容量,构造左右头节点get函数:从hash表中寻找节点,并将节点移除重新插入put函数:
- 从hash表中寻找key,如果存在则修改value,将节点重新移除插入如果不存在则加入缓存
- 如果缓存满了,移除最右边的节点,更新哈希表将key,value加入缓存,更新hash表
class LRUCache {
public:
// 1. 构造数据结构,包含key和value,左右节点。
// 2. 构造删除插入函数。
// 3. 初始化函数,包括容量,构造左右头节点
// 4. get函数:从hash表中寻找节点,并将节点移除重新插入
// 5. put函数:
// 1. 从hash表中寻找key,如果存在则修改value,将节点重新移除插入
// 2. 如果不存在则加入缓存
// 1. 如果缓存满了,移除最右边的节点,更新哈希表
// 2. 将key,value加入缓存,更新hash表
struct Node{
int key, value;
Node *left, *right;
Node(int _key, int _value):key(_key), value(_value), left(NULL), right(NULL){}
}*L, *R;
int n;
unordered_map hash;
void remove(Node* p) {
p->right->left = p->left;
p->left->right = p->right;
}
void insert(Node* p) {
p->right = L->right;
p->left = L;
L->right->left = p;
L->right = p;
}
LRUCache(int capacity) {
n = capacity;
L = new Node(-1, -1), R = new Node(-1, -1);
L->right = R;
R->left = L;
}
int get(int key) {
if (hash.count(key) == 0) return -1;
auto p = hash[key];
remove(p);
insert(p);
return p->value;
}
void put(int key, int value) {
if (hash.count(key)) {
auto p = hash[key];
p->value = value;
remove(p);
insert(p);
} else {
if (hash.size() == n) {
auto p = R->left;
remove(p);
hash.erase(p->key);
delete p;
}
auto p = new Node(key, value);
hash[key] = p;
insert(p);
}
}
};



