運用你所掌握的數據結構,設計和實現一個 LRU (最近最少使用) 緩存機制。它應該支持以下操作: 獲取數據 get
和 寫入數據 put
。
獲取數據 get(key)
- 如果密鑰 (key) 存在於緩存中,則獲取密鑰的值(總是正數),否則返回 -1。
寫入數據 put(key, value)
- 如果密鑰已經存在,則變更其數據值;如果密鑰不存在,則插入該組「密鑰/數據值」。當緩存容量達到上限時,它應該在寫入新數據之前刪除最久未使用的數據值,從而爲新的數據值留出空間。
進階:
你是否可以在 O(1) 時間複雜度內完成這兩種操作?
示例:
LRUCache cache = new LRUCache( 2 /* 緩存容量 */ ); cache.put(1, 1); cache.put(2, 2); cache.get(1); // 返回 1 cache.put(3, 3); // 該操作會使得密鑰 2 作廢 cache.get(2); // 返回 -1 (未找到) cache.put(4, 4); // 該操作會使得密鑰 1 作廢 cache.get(1); // 返回 -1 (未找到) cache.get(3); // 返回 3 cache.get(4); // 返回 4
想法
雙向鏈表
誰被使用了,就放到鏈表頭去
get 遍歷鏈表,找到,就放到鏈表頭去
put 如果找到,更新值
插入到鏈表頭,表滿了後刪除鏈表尾
#include <iostream>
#include <list>
using namespace std;
class node{
public:
int key;
int val;
node *pre;
node *next;
node(){
key = -1;
val = -1;
pre = NULL;
next = NULL;
}
};
class LRUCache {
public:
node *root = new node;
int num;
int capa;
node *p;
LRUCache(int capacity) {
num = 0;
capa = capacity;
}
int get(int key){
p = root;
while(true){
if(p -> key == key){
if(p -> next != NULL){
p -> next -> pre = p -> pre;
p -> pre -> next = p -> next;
}
else{
p -> pre -> next = p -> next;
}
if(root -> next != NULL){
p -> next = root -> next;
root -> next -> pre = p;
}
p -> pre = root;
root -> next = p;
cout << p -> val << endl;
return p -> val;
}
if(p -> next == NULL){
cout << -1 << endl;
return -1;
}
else{
p = p -> next;
}
}
}
void put(int key, int value) {
node *q;
p = root;
while(true){
if(p -> key == key){
p -> val = value;
cout << p -> val << "change"<< endl;
if(p -> next != NULL){
p -> next -> pre = p -> pre;
p -> pre -> next = p -> next;
}
else{
p -> pre -> next = p -> next;
}
if(root -> next != NULL){
p -> next = root -> next;
root -> next -> pre = p;
}
p -> pre = root;
root -> next = p;
return;
}
if(p -> next == NULL){
q = p;
break;
}
else{
p = p -> next;
}
}
if(num >= capa){
cout << "delete" << endl;
q -> pre -> next = NULL;
}
else{
num++;
}
cout << "add"<< endl;
node *p = new node;
p -> key = key;
p -> val = value;
if(root -> next != NULL){
p -> next = root -> next;
root -> next -> pre = p;
}
p -> pre = root;
root -> next = p;
}
};
int main(){
LRUCache cache = LRUCache(2);
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 該操作會使得密鑰 2 作廢
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 該操作會使得密鑰 1 作廢
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4
}