前言
什麼是lru演算法,就是一種快取淘汰策略。
計算機的快取容量有限,如果快取滿了就要刪除一些內容,給新內容騰位置。但問題是,刪除哪些內容呢?我們肯定希望刪掉哪些沒什麼用的快取,而把有用的資料繼續留在快取裡,方便之後繼續使用。那麼,什麼樣的資料,我們判定為「有用的」的資料呢?
lru 快取淘汰演算法就是一種常用策略。lru 的全稱是 least recently used,也就是說我們認為最近使用過的資料應該是是「有用的」,很久都沒用過的資料應該是無用的,記憶體滿了就優先刪那些很久沒用過的資料。
lru快取機制對應leetcode 146。
運用你所掌握的資料結構,設計和實現乙個 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操作: 有找到 返回值,並且將它置為"最近使用",沒有找到 返回 -1
put操作:存在值 更新並且將它置為"最近使用",不存在值 容量夠,增加,放在"最近使用"。容量不夠 刪除使用頻次最少的 增加放在"最近使用"
使用佇列可以將剛使用的放在佇列頭,這樣佇列尾就是最近沒使用的,淘汰的話先淘汰佇列尾的,最近使用的放在佇列頭。單純的佇列是不行的,需要雙向鍊錶,比如我們想把中間的值提出來,想將這個值的前繼節點和後繼節點進行相連。
但是get操作無法o(1)get到操作,佇列中只能遍歷查詢值。如果更快get到值可以使用hashmap的資料結構。
將兩種資料結構相結合成雜湊鍊錶,如下圖所示
// 有找到 返回值,並且將它置為最新使用
// 沒有找到 返回 -1
public int get(int key) else
}// 存在值 更新並且將它置為最新使用
// 不存在值 容量夠,增加
// 容量不夠 刪除使用頻次最少的 增加放在最近使用
public void put(int key, int value) else
doublelist.addfirst(toaddnode);
map.put(key, toaddnode);}}
class lrunode
}class doublelist
/*** 往雙向鍊錶頭部插入
** @param node
*/public void addfirst(lrunode node)
/*** 刪除鍊錶中x 節點 x一定存在
** @param x
*/public void delnode(lrunode x)
/*** 刪除結尾節點 返回該節點
** @return
*/public lrunode removelast()
lrunode removenode = tail.pre;
delnode(removenode);
return removenode;
}/**
* 返回鍊錶長度
** @return
*/public int getlistsize() }}
很容易犯錯的一點是:處理鍊錶節點的同時不要忘了更新雜湊表中對節點的對映。
references
LRU快取機制
運用你所掌握的資料結構,設計和實現乙個 lru 最近最少使用 快取機制。它應該支援以下操作 獲取資料 get 和 寫入資料 put 獲取資料 get key 如果金鑰 key 存在於快取中,則獲取金鑰的值 總是正數 否則返回 1。寫入資料 put key,value 如果金鑰不存在,則寫入其資料值。...
LRU快取機制
運用你所掌握的資料結構,設計和實現乙個 lru 最近最少使用 快取機制。它應該支援以下操作 獲取資料 get 和 寫入資料 put 獲取資料 get key 如果金鑰 key 存在於快取中,則獲取金鑰的值 總是正數 否則返回 1。寫入資料 put key,value 如果金鑰不存在,則寫入其資料值。...
LRU快取機制
lru快取機制 最近最少使用 雙向鍊錶 雜湊表 不使用自帶 linkedhashmap 雙向鍊錶按照被使用的順序儲存了這些鍵值對,靠近頭部的鍵值對是最近使用的,而靠近尾部的鍵值對是最久未使用的。雜湊錶即為普通的雜湊對映 hashmap 通過快取資料的鍵對映到其在雙向鍊錶中的位置。首先使用雜湊表進行定...