[Leetcode]146.LRU快取機制

AdamWong發表於2018-12-30

Leetcode難題,題目為:

運用你所掌握的資料結構,設計和實現一個  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
這一題是非常典型的應用STL的演算法題,同時還通過這個讓我們瞭解了一下系統內的LRU快取機制
這一題用的是unordered_map,list,pair這幾個STL常用的東西。如果不清楚的朋友可以查詢Cpp reference,下面題解給了註釋

題解以及註釋

 

 1 class LRUCache {
 2 public:
 3     /*建構函式*/
 4     LRUCache(int capacity) : _capacity(capacity) {}
 5     int get(int key) {
 6         if (pos.find(key) != pos.end()) {
 7             /*如果找到這個key所對應的值*/
 8             put(key, pos[key]->second);
 9             return pos[key]->second;
10         }
11         return -1;
12     }
13     void put(int key, int value) {
14         if (pos.find(key) != pos.end())
15             recent.erase(pos[key]);
16         else if (recent.size() >= _capacity) {
17             /*超出容量了,從pos和recent都刪除出現最早的那一個*/
18             pos.erase(recent.back().first);
19             recent.pop_back();
20         }
21         recent.push_front({ key, value });
22         pos[key] = recent.begin();
23     }
24 private:
25     int _capacity;
26     list<pair<int, int>> recent;
27     /*最近使用過的記錄,pair<int,int>表示鍵值對,用list模擬佇列*/
28     unordered_map<int, list<pair<int, int>>::iterator> pos;  
29     /****************
30       value儲存的是一個迭代器,這是一個從key對映到位置的hash表,
31       這裡沒有再用value的原因是可以直接通過迭代器的位置找到value
32      ***************/
33 };

 




相關文章