146 LRU 快取機制(雙向鍊錶 雜湊表)

2021-10-21 15:30:51 字數 3440 閱讀 5178

難度:中等

運用你所掌握的資料結構,設計和實現乙個 lru (最近最少使用) 快取機制 。

實現 lrucache 類:

lrucache(int capacity) 以正整數作為容量 capacity 初始化 lru 快取

int get(int key) 如果關鍵字 key 存在於快取中,則返回關鍵字的值,否則返回 -1 。

void put(int key, int value) 如果關鍵字已經存在,則變更其資料值;如果關鍵字不存在,則插入該組「關鍵字-值」。當快取容量達到上限時,它應該在寫入新資料之前刪除最久未使用的資料值,從而為新的資料值留出空間。

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

示例:

輸入

[「lrucache」, 「put」, 「put」, 「get」, 「put」, 「get」, 「put」, 「get」, 「get」, 「get」]

[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]

輸出

[null, null, null, 1, null, -1, null, -1, 3, 4]

解釋

lrucache lrucache = new lrucache(2);

lrucache.put(1, 1); // 快取是

lrucache.put(2, 2); // 快取是

lrucache.get(1); // 返回 1

lrucache.put(3, 3); // 該操作會使得關鍵字 2 作廢,快取是

lrucache.get(2); // 返回 -1 (未找到)

lrucache.put(4, 4); // 該操作會使得關鍵字 1 作廢,快取是

lrucache.get(1); // 返回 -1 (未找到)

lrucache.get(3); // 返回 3

lrucache.get(4); // 返回 4

解題思路:

本題使用雙向鍊錶和雜湊表來解決。使用鍊錶是為了表示頭部的鍵值對是最近使用的,而尾部的鍵值對是最久沒有使用的。那為什麼不使用單鏈表呢?因為一旦刪除了尾結點,我們無法知道尾結點的上乙個節點是誰,所以需要在尾結點前加入pre指向前乙個節點,也就是雙向鍊錶。使用雜湊表的目的是可以在o(1)時間內找到key所對應的節點,這個節點存有key所對應的value。

python**:

# 雙向鍊錶+雜湊表

class

dlinkednode

:def

__init__

(self, key=

0, value=0)

->

none

: self.key = key

self.value = value

self.prev =

none

self.

next

=none

class

lrucache

:def

__init__

(self, capacity:

int)

: self.capacity = capacity

self.hash_map =

dict()

self.head = dlinkednode(

) self.tail = dlinkednode(

) self.head.

next

= self.tail

self.tail.prev = self.head

self.size =

0def

get(self, key:

int)

->

int:

if key in self.hash_map:

self.removenode(self.hash_map[key]

) self.movetohead(self.hash_map[key]

)return self.hash_map[key]

.value

else

:return-1

defput

(self, key:

int, value:

int)

->

none

:if key in self.hash_map:

self.hash_map[key]

.value = value

self.removenode(self.hash_map[key]

) self.movetohead(self.hash_map[key]

)else

: node = dlinkednode(key, value)

if self.size < self.capacity:

self.size +=

1else

: self.hash_map.pop(self.tail.prev.key)

self.removenode(self.tail.prev)

self.hash_map[key]

= node

self.movetohead(node)

defremovenode

(self, node)

: node.

next

.prev = node.prev

node.prev.

next

= node.

next

defmovetohead

(self, node)

: node.

next

= self.head.

next

self.head.

next

.prev = node

self.head.

next

= node

node.prev = self.head

# your lrucache object will be instantiated and called as such:

# obj = lrucache(capacity)

# param_1 = obj.get(key)

# obj.put(key,value)

複雜度分析:

力扣 146LRU快取機制(雙向鍊錶)

題目描述 運用你所掌握的資料結構,設計和實現乙個 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 如果金鑰不存在,則寫入其資料值。當快取容量...