146 LRU快取機制

2021-10-06 11:18:26 字數 1628 閱讀 7715

運用你所掌握的資料結構,設計和實現乙個 lru (最近最少使用) 快取機制。它應該支援以下操作: 獲取資料 get 和 寫入資料 put 。

獲取資料 get(key) - 如果金鑰 (key) 存在於快取中,則獲取金鑰的值(總是正數),否則返回 -1。 寫入資料 put(key,value) 。

如果金鑰已經存在,則變更其資料值;如果金鑰不存在,則插入該組「金鑰/資料值」。當快取容量達到上限時,它應該在寫入新資料之前刪除最久未使用的資料值,從而為新的資料值留出空間。

高階:你是否可以在 o(1) 時間複雜度內完成這兩種操作?

當看到需要用o(1)的時間複雜度完成取值和存值操作時,一般就會想到用哈係表了,可以用哈係表維護key-value對,從而實現get和put資料的時間複雜度是o(1)。

題目還需要實現lru刪除機制,因而可以考慮用乙個雙向鍊錶來維護資料的使用頻數,當put資料時,將key-value建立哈係表的同時,將key-value作為乙個節點插入到鍊錶頭部。當get資料或者put的資料key存在時,可以把鍊錶中對應key的節點從鍊錶中刪除,再插入到鍊錶頭部。這樣鍊錶尾部的節點必定是最近最少使用的,容量滿了直接刪除尾部節點即可。

但是雙向鍊錶的查詢節點時間複雜度是o(n),明顯不符合要求。因而可以結合哈係表來使用,哈係表儲存key和對應的鍊錶節點,就可以在o(1)的時間內找到鍊錶中對應的節點進行操作了。(這個方法很有技巧性,需記住)。

涉及鍊錶的題目,都可以考慮建立乙個偽頭部節點和偽尾部節點,不用進行麻煩的資料插入檢查。

//雙向鍊錶節點

struct dlinkednode

dlinkednode

(int _key,

int _value)};

class

lrucache

//獲取資料,資料存在時直接將節點移動鍊錶頭部

intget

(int key)

else

}//插入資料時,資料不存在建立哈系對映,並且將節點插入鍊錶頭部

//資料存在時,通過哈係表獲得節點,修改value,再移動到鍊錶頭部

void

put(

int key,

int value)

}else

}//刪除鍊錶的節點

void

removenode

(dlinkednode* node)

//節點新增到鍊錶頭部

void

addtohead

(dlinkednode* node)

//鍊錶節點移動到頭部

void

removetohead

(dlinkednode* node)

//刪除鍊錶尾部節點

dlinkednode*

removetail()

};/** * your lrucache object will be instantiated and called as such:

* lrucache* obj = new lrucache(capacity);

* int param_1 = obj->get(key);

* obj->put(key,value);

*/

146 LRU快取機制

運用你所掌握的資料結構,設計和實現乙個 lru 最近最少使用 快取機制。它應該支援以下操作 獲取資料get和 寫入資料put。獲取資料get key 如果金鑰 key 存在於快取中,則獲取金鑰的值 總是正數 否則返回 1。寫入資料put key,value 如果金鑰不存在,則寫入其資料值。當快取容量...

146 LRU快取機制

運用你所掌握的資料結構,設計和實現乙個 lru 最近最少使用 快取機制。它應該支援以下操作 獲取資料get和 寫入資料put。獲取資料get key 如果金鑰 key 存在於快取中,則獲取金鑰的值 總是正數 否則返回 1。寫入資料put key,value 如果金鑰不存在,則寫入其資料值。當快取容量...

146 LRU快取機制

運用你所掌握的資料結構,設計和實現乙個 lru 最近最少使用 快取機制。它應該支援以下操作 獲取資料 get 和 寫入資料 put 獲取資料 get key 如果金鑰 key 存在於快取中,則獲取金鑰的值 總是正數 否則返回 1。寫入資料 put key,value 如果金鑰不存在,則寫入其資料值。...