题目
代码(首刷看解析,折腾惨了)
加入一个哈希表和链表来实现。
每次获取的时候,就取哈希表中的对应key
,该key指向的是链表的迭代器位置,将他从链表中删除(链表中的erase的参数是迭代器,而哈希表的erase是值),并且重新用emplace_front
插入头部。这里的插入用到的是emplace_front
,可以直接将参数放在括号里。最后更新哈希表中key的值。
插入也是这个道理,如果满了就删除链表的back()
和对应哈希表的key。没有满就直接插入或者修改值,修改值的时候要记得将链表的值放到头部,哈希表也要跟着修改。
class LRUCache {
public:
LRUCache(int capacity) {
this->cap = capacity;
}
int get(int key) {
auto it = mp.find(key);
if(it == mp.end())
return -1;
int ans = it->second->second;
ls.erase(mp[key]);
ls.emplace_front(key, ans);
mp[key] = ls.begin();
return ans;
}
void put(int key, int value) {
if(ls.size() >= cap) { // 满了
if(mp.find(key) == mp.end()) { // 删除最后一个
int num = ls.back().first; // key
mp.erase(num);
ls.pop_back();
ls.emplace_front(key, value);
mp[key] = ls.begin();
} else { // 不需要删除
ls.erase(mp[key]);
ls.emplace_front(key, value);
mp[key] = ls.begin();
}
} else { // 没有满
if(mp.find(key) == mp.end()) {
ls.emplace_front(key, value);
mp[key] = ls.begin();
} else {
ls.erase(mp[key]);
ls.emplace_front(key, value);
mp[key] = ls.begin();
}
}
}
private:
int cap;
list<pair<int, int>> ls;
unordered_map<int, list<pair<int, int>>::iterator> mp;
};
代码(8.4 二刷看解析 GO)
考场上估计也是得让你手写一个双向链表,之前都是用的list和unordered_map
type LRUCache struct {
size int
cap int
cache map[int]*linkNode
head, tail *linkNode
}
type linkNode struct {
key, value int
pre, next *linkNode
}
func Constructor(capacity int) LRUCache {
l := LRUCache{
cap: capacity,
cache: map[int]*linkNode{},
head: &linkNode{key: 0, value: 0},
tail: &linkNode{key: 0, value: 0},
}
l.head.next = l.tail
l.tail.pre = l.head
return l
}
func (this *LRUCache) Get(key int) int {
if _, ok := this.cache[key]; ok {
node := this.cache[key] // 找到key的指针
// 删除节点
node.pre.next = node.next
node.next.pre = node.pre
// 插入头部
node.pre = this.head
node.next = this.head.next
this.head.next.pre = node
this.head.next = node
return node.value
}
return -1
}
func (this *LRUCache) Put(key int, value int) {
if _, ok := this.cache[key]; !ok { // 未找到
node := &linkNode{key: key, value: value}
this.cache[key] = node // 指针
// 插入头部
node.pre = this.head
node.next = this.head.next
this.head.next.pre = node
this.head.next = node
this.size++
if this.size > this.cap {
removed := this.tail.pre
// 删除节点
removed.pre.next = removed.next
removed.next.pre = removed.pre
delete(this.cache, removed.key) // 从哈希表删除
this.size--
}
} else {
node := this.cache[key]
node.value = value
// 删除节点
node.pre.next = node.next
node.next.pre = node.pre
// 插入头部
node.pre = this.head
node.next = this.head.next
this.head.next.pre = node
this.head.next = node
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* obj := Constructor(capacity);
* param_1 := obj.Get(key);
* obj.Put(key,value);
*/
代码(8.31 三刷看解析,自己构造双向链表)
class node {
public:
node(int key = -1, int val = -1, node* prev = nullptr, node* next = nullptr) : prev(prev), next(next), key(key), val(val){}
node* prev, *next;
int key, val;
};
class LRUCache {
public:
int cap, size;
node head, tail;
unordered_map<int, node*> map; // key, node
LRUCache(int capacity) {
cap = capacity;
size = 0;
head.next = &tail;
tail.prev = &head;
}
int get(int key) {
if(!map.count(key))
return -1;
auto cur = map[key];
eraseNode(cur);
insertHead(cur);
return cur->val;
}
void put(int key, int value) {
if(map.count(key)) {
auto no = map[key];
eraseNode(no);
insertHead(no);
no->val = value;
return;
}
auto newNode = new node(key, value);
if(cap == size) {
auto deleteNoded = tail.prev;
eraseNode(deleteNoded);
map.erase(map.find(deleteNoded->key));
delete deleteNoded;
size--;
}
insertHead(newNode);
map[key] = newNode;
size++;
}
void eraseNode(node* no) {
auto prevno = no->prev;
auto nextno = no->next;
prevno->next = nextno;
nextno->prev = prevno;
no->next = nullptr;
no->prev = nullptr;
}
void insertHead(node* cur) {
// 插入头部
auto headnext = head.next;
head.next = cur;
headnext->prev = cur;
cur->prev = &head;
cur->next = headnext;
}
};
代码(9.19 四刷自解)
struct node {
node* pre, *next;
int key, value;
node(int k = 0, int v = 0, node* pre = nullptr, node* next = nullptr) : key(k), value(v){}
};
class LRUCache {
public:
unordered_map<int, node*> mp;
node head, tail;
int cap, size;
LRUCache(int capacity) {
cap = capacity;
head.next = &tail;
tail.pre = &head;
size = 0;
}
int get(int key) {
if(!mp.count(key))
return -1;
auto ptr = mp[key];
deletePtr(ptr);
insertHead(ptr);
return ptr->value;
}
void put(int key, int value) {
if(!mp.count(key)) { // 不存在
if(size >= cap) {
auto del = tail.pre;
deletePtr(del);
mp.erase(mp.find(del->key));
delete del;
auto ptr = new node(key, value);
mp[key] = ptr;
insertHead(ptr);
} else {
auto ptr = new node(key, value);
mp[key] = ptr;
insertHead(ptr);
size++;
}
} else { // 存在
auto ptr = mp[key];
ptr->value = value;
deletePtr(ptr);
insertHead(ptr);
}
}
void deletePtr(node* ptr) {
auto pre = ptr->pre, next = ptr->next;
pre->next = next;
next->pre = pre;
ptr->next = nullptr;
ptr->pre = nullptr;
}
void insertHead(node* ptr) {
auto tmp = head.next;
ptr->pre = &head;
head.next = ptr;
ptr->next = tmp;
tmp->pre = ptr;
}
};
代码(10.3 库函数)
class LRUCache {
public:
unordered_map<int, list<pair<int, int>>::iterator> mp;
list<pair<int, int>> ls;
int cap;
LRUCache(int capacity) : cap(capacity){}
int get(int key) {
if(!mp.count(key))
return -1;
auto it = mp[key];
int ans = it->second;
ls.erase(it);
ls.emplace_front(key, ans);
mp[key] = ls.begin();
return ans;
}
void put(int key, int value) {
if(mp.count(key)) {
auto it = mp[key];
ls.erase(it);
ls.emplace_front(key, value);
mp[key] = ls.begin();
} else {
if(mp.size() >= cap) {
auto back = ls.back();
mp.erase(back.first);
ls.pop_back();
}
ls.emplace_front(key, value);
mp[key] = ls.begin();
}
}
};