微軟面試題: LeetCode 146. LRU 緩存機制 middle 出現次數:3

實現一個  LRUCache 類:使得 put 和  get 操做都達到 O(1)node

 哈希表 + 雙向隊列緩存

雙向隊列 中存儲 緩存(頁面)信息,使用哈希表能夠實現O(1) 找到 緩存的位置,使用雙向隊列能夠 實現O(1)函數

時間的從頭部插入(更新剛用過的頁爲最新狀態)和從尾部刪除(淘汰最近最久未使用的頁)。spa

直接上代碼:code

 1 struct Node
 2 {
 3     int key;
 4     int value;
 5     Node(int k,int v):key(k),value(v){}
 6 };
 7 class LRUCache {
 8 public:
 9     LRUCache(int capacity):buff_size(capacity) {}
10     
11     int get(int key)
12     {
13         // get 操做 缺頁,直接返回 -1
14         if(hash_table.find(key) == hash_table.end())
15         {
16             return -1;
17         }
18         // 藉助哈希表O(1)實現 get操做
19         int value = hash_table[key]->value;
20         // 刷新當前頁爲最新
21         put( key, value);
22        // Cache.splice(Cache.begin(), Cache,hash_table[key]);
23         return value;
24     }
25     
26     void put(int key, int value)
27     {
28         //未命中且Cache已滿,淘汰最近最久未使用頁,
29         if(hash_table.find(key) == hash_table.end() && Cache.size() == buff_size)
30         {
31             int key = Cache.back().key;
32             Cache.pop_back();//淘汰最近最久未使用頁
33             hash_table.erase(key);//同時刪除hash表中對應的記錄
34         }
35         //命中 刪除掉Cache中目標記錄,此時hash表可不更新,由於該頁立刻就要再插入Cache
36         if(hash_table.find(key) != hash_table.end())
37         {
38             Cache.erase(hash_table[key]);
39         }
40         //將當前頁面從新插入到Cache 頭部,同時更新hash表記錄當前頁最新位置
41         Node node(key,value);
42         Cache.push_front(node);
43         hash_table[key] = Cache.begin();
44         return;
45     }
46 private:
47     int buff_size;
48     list<Node> Cache;
49     unordered_map<int,list<Node>::iterator> hash_table;
50 };
51 
52 /**
53  * Your LRUCache object will be instantiated and called as such:
54  * LRUCache* obj = new LRUCache(capacity);
55  * int param_1 = obj->get(key);
56  * obj->put(key,value);
57  */

 

使用 list 的splice 函數 ,能夠提升效率 ,代碼以下:blog

 1 struct Node
 2 {
 3     int key;
 4     int value;
 5     Node(int k,int v):key(k),value(v){}
 6 };
 7 class LRUCache {
 8 public:
 9     LRUCache(int capacity):buff_size(capacity) {}
10     
11     int get(int key)
12     {
13         // get 操做 缺頁,直接返回 -1
14         if(hash_table.find(key) == hash_table.end())
15         {
16             return -1;
17         }
18         // 藉助哈希表O(1)實現 get操做
19         int value = hash_table[key]->value;
20         // 刷新當前頁爲最新
21         //put( key, value);
22           Cache.splice(Cache.begin(), Cache,hash_table[key]);
23         return value;
24     }
25     
26     void put(int key, int value)
27     {
28         //命中 刪除掉Cache中目標記錄,此時hash表可不更新,由於該頁立刻就要再插入Cache
29         if(hash_table.find(key) != hash_table.end())
30         {
31             hash_table[key]->value = value;
32             return Cache.splice(Cache.begin(), Cache,hash_table[key]);
33         }
34         //將當前頁面從新插入到Cache 頭部,同時更新hash表記錄當前頁最新位置
35         Node node(key,value);
36         Cache.push_front(node);
37         hash_table[key] = Cache.begin();
38         if(Cache.size() > buff_size)
39         {
40             hash_table.erase(Cache.back().key);
41             Cache.pop_back();
42         }
43         return;
44     }
45 private:
46     int buff_size;
47     list<Node> Cache;
48     unordered_map<int,list<Node>::iterator> hash_table;
49 };
50 
51 /**
52  * Your LRUCache object will be instantiated and called as such:
53  * LRUCache* obj = new LRUCache(capacity);
54  * int param_1 = obj->get(key);
55  * obj->put(key,value);
56  */
相關文章
相關標籤/搜索