運用你所掌握的資料結構,設計和實現乙個 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
在解答這到題之前我們先看看看什麼是lru
lru(英文:least recently used )
它是記憶體管理的一種頁面置換演算法,對於在記憶體中但又不用的資料塊(記憶體塊)叫做lru,作業系統會根據哪些資料屬於lru而將其移出記憶體而騰出空間來載入另外的資料。
lru演算法:最近最少使用,簡單來說就是將資料塊中,每次使用過的資料放在資料塊的最前端,然後將存在的時間最長的,也就是資料塊的末端的資料剔除掉,這個演算法的精髓在於如果一塊資料最近被訪問,那麼它將來被訪問的機率也很高,根據資料的歷史訪問來淘汰長時間未使用的資料,這就是lru演算法。
那麼為什麼需要這個演算法呢??
關於作業系統的記憶體管理,如何節省利用容量不大的記憶體為最多的程序提供資源,一直是研究的重要方向。而記憶體的虛擬儲存管理,是現在最通用,最成功的方式—— 在記憶體有限的情況下,擴充套件一部分外存作為虛擬記憶體,真正的記憶體只儲存當前執行時所用得到資訊。這無疑極大地擴充了記憶體的功能,極大地提高了計算機的併發度。虛擬頁式儲存管理,則是將程序所需空間劃分為多個頁面,記憶體中只存放當前所需頁面,其餘頁面放入外存的管理方式。
然而,有利就有弊,虛擬頁式儲存管理增加了程序所需的記憶體空間,卻也帶來了執行時間變長這一缺點:程序執行過程中,不可避免地要把在外存中存放的一些資訊和記憶體中已有的進行交換,由於外存的低速,這一步驟所花費的時間不可忽略。因而,採取盡量好的演算法以減少讀取外存的次數,也是相當有意義的事情。
所以,我們解題的思路就出來了:
1.我們需要用棧的思想來想一下。棧頂就是最近剛訪問的,而棧底就是最久沒訪問過的。
2.需要以個hashmap來保證裡面的資料不重複。
需要明確的:
1.新增節點:新節點插入到表頭即可,時間複雜度o(1)
2.查詢節點:每次節點被查詢到時,將節點移動到鍊錶頭部,時間複雜度o(n)
3. 替換節點:查詢到後替換(更新節點value),將節點移動到鍊錶頭部;
對於下乙個頁面的情況;
1.棧中存在:則需要更新棧頂元素,就是將當前存在的頁號放到棧頂。
2.棧中並未存在:
2.1.棧未滿:直接將該頁放到棧頂。
2.2.棧已滿:需要選乙個最近最久未訪問的將它置換出,然後將該頁放到棧頂。
**如下:
class lrucachepublic int get(int key)
boolean old = stack.remove(integer.valueof(key)); //棧中存在
stack.push(key);
return map.get(key);
}public void put(int key, int value) else
}stack.add(key);
map.put(key,value);
}}
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 通過快取資料的鍵對映到其在雙向鍊錶中的位置。首先使用雜湊表進行定...