設計LRU快取結構

2021-10-22 18:41:17 字數 2683 閱讀 3132

設計lru快取結構

描述

設計lru快取結構,該結構在構造時確定大小,假設大小為k,並有如下兩個功能

要求

set和get方法的時間複雜度為o(1)

某個key的set或get操作一旦發生,認為這個key的記錄成了最常使用的。

當快取的大小超過k時,移除最不經常使用的記錄,即set或get最久遠的。

若opt=1,接下來兩個整數x, y,表示set(x, y)

若opt=2,接下來乙個整數x,表示get(x),若x未出現過或已被移除,則返回-1

對於每個操作2,輸出乙個答案

示例

輸入:[[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]],3

返回值:[1,-1]

說明:第一次操作後:最常使用的記錄為("1", 1)

第二次操作後:最常使用的記錄為("2", 2),("1", 1)變為最不常用的

第三次操作後:最常使用的記錄為("3", 2),("1", 1)還是最不常用的

第四次操作後:最常用的記錄為("1", 1),("2", 2)變為最不常用的

第五次操作後:大小超過了3,所以移除此時最不常使用的記錄("2", 2),加入記錄("4", 4),並且為最常使用的記錄,然後("3", 2)變為最不常使用的記錄

讀完題目之後,注意到set和get的時間複雜度都為o(1),因此首先想到的是使用map結構。接著,lru的讀取和寫入操作都需要將元素設定為最常使用,其中寫入操作當元素個數大於等於容量k時,還需要將最不經常使用的元素從圖中移除。因此,我們想到需要將陣列按照使用時間的先後順序排序。結合上述兩點:map結構 + 時間有序,想到使用linkedhashmap來解決這道題。

遍歷所給的二維陣列,根據每個陣列的第乙個字段判斷是set還是get。如果是set,需要判斷元素總數和容量k的關係,容量小於k時,將元素加入map,大於等於k時,移除鍊錶中的第乙個元素(即最不常用的元素)。如果是get,map中存在key時,將其對應的值返回,並把元素從map中刪除,重新加入鍊錶。否則返回-1。

public

class

solution

map.

put(key,operators[i][2

]);break

;case2:

if(map.

containskey

(key)

)else

break;}

}int

result =

newint

[list.

size()

];for(

int i =

0; i < list.

size()

; i++

)return result;

}}

什麼是lru?

lru英文全稱least recently used,可以理解為最久沒有使用。在這種策略下我們用最近一次使用的時間來衡量一塊記憶體的價值,越久之前使用的價值也就越低,最近剛剛使用過的,後面接著會用到的概率也就越大,那麼自然也就價值越高。

當然只有這個限制是不夠的,我們前面也說了,由於記憶體是非常金貴的,導致我們可以儲存在快取當中的資料是有限的。比如說我們固定只能儲存1w條,當記憶體滿了之後,快取每插入一條新資料,都要拋棄一條最長沒有使用的舊資料。這樣我們就保證了快取當中的資料的價值都比較高,並且記憶體不會超過限制。

保證快取的讀寫效率,比如讀寫的複雜度都是o(1)

當一條快取當中的資料被讀取,將它最近使用的時間更新

當插入一條新資料的時候,彈出更新時間最遠的資料

lru原理

我們仔細想一下這個問題會發現好像沒有那麼簡單,顯然我們不能通過陣列來實現這個快取。因為陣列的查詢速度是很慢的,不可能做到o(1)。其次我們用hashmap好像也不行,因為雖然查詢的速度可以做到o(1),但是我們沒辦法做到更新最近使用的時間,並且快速找出最遠更新的資料。

如果是在面試當中被問到想到這裡的時候,可能很多人都已經束手無策了。但是先別著急,我們冷靜下來想想會發現問題其實並沒有那麼模糊。首先hashmap是一定要用的,因為只有hashmap才可以做到o(1)時間內的讀寫,其他的資料結構幾乎都不可行。但是只有hashmap解決不了更新以及淘汰的問題,必須要配合其他資料結構進行。這個資料結構需要能夠做到快速地插入和刪除,其實我這麼一說已經很明顯了,只有乙個資料結構可以做到,就是鍊錶。

鍊錶有乙個問題是我們想要查詢鍊錶當中的某乙個節點需要o(n)的時間,這也是我們無法接受的。但這個問題並非無法解決,實際上解決也很簡單,我們只需要把鍊錶當中的節點作為hashmap中的value進行儲存即可,最後得到的系統架構如下:

設計LRU快取結構

設計lru快取結構 設計lru快取結構,該結構在構造時確定大小,假設大小為k,並有如下兩個功能 要求 set和get方法的時間複雜度為o 1 某個key的set或get操作一旦發生,認為這個key的記錄成了最常使用的。當快取的大小超過k時,移除最不經常使用的記錄,即set或get最久遠的。輸入描述 ...

LRU快取設計

設計乙個lru演算法 最近最少移除 來實現快取 思路 public class lrucache 刪除中間節點 public void remove string key 刪除節點 param node public string removenode node node else if node ...

NC93 設計LRU快取結構

知識點 雜湊表 鍊錶 題目鏈結 題目描述 設計lru快取結構,該結構在構造時確定大小,假設大小為k,並有如下兩個功能 要求 set和get方法的時間複雜度為o 1 某個key的set或get操作一旦發生,認為這個key的記錄成了最常使用的。當快取的大小超過k時,移除最不經常使用的記錄,即set或ge...