運用你所掌握的數據結構,設計和實現一個 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
tips:
數據結構:用unordered_map實現O(1)內訪問,用list的O(1)時間的插入刪除特性,實現維護緩衝區的大小以及優先順序。
class LRUCache {
private:
int capacity;
list<pair<int,int>> cache;
unordered_map<int, list<pair<int,int>>::iterator> mymap;
public:
LRUCache(int cap) {
capacity=cap;
}
int get(int key) {
if(mymap.find(key)!=mymap.end()) {
auto iter= mymap[key];
int val=(*iter).second;
cache.erase(iter);
cache.push_front({key,val});
mymap[key]=cache.begin();
return val;
} else {
return -1;
}
}
void put(int key, int value) {
if(mymap.find(key)!=mymap.end()) {
auto iter= mymap[key];
cache.erase(iter);
cache.push_front({key,value});
mymap[key]=cache.begin();
} else {
// 判斷容量是否已滿
if(cache.size() == capacity) {
auto back=cache.back();
mymap.erase(back.first);
cache.pop_back();
}
cache.push_front({key,value});
mymap[key]=cache.begin();
}
}
};