146 LRU快取機制

2021-10-03 03:37:12 字數 3439 閱讀 6857

參考:官方解答

主要思路

需要字典實現快速查詢,同時需要保證一定的順序。帶頭尾節點的雙向鍊錶可以實現快速刪除和新增頭尾節點。因為節點的屬性包括前乙個節點和後乙個節點,即使是中間的節點也可以實現快速刪除。

思路1: 使用ordereddict實現(可參考 python ordereddict 詳解)

時間複雜度:o(1)。有序字典中的所有操作:get / in / set / move_to_end / popitem 都可以在常數時間內完成。

空間複雜度:o(capacity)。這裡儲存最多 capacity + 1 個元素,達到就刪除乙個

#  後面的剛剛訪問過,前面的很久沒使用

from collections import ordereddict

class

lrucache

(ordereddict)

:def

__init__

(self, capacity:

int)

: self.capacity = capacity

defget(self, key:

int)

->

int:

# get: 存在就返回值,並移動後面,不存在就返回-1

if key not

in self.keys():

return-1

else

: self.move_to_end(key)

return self[key]

defput

(self, key:

int, value:

int)

->

none

:# put: 存在就移到後面並修改值,不存在就在後面插入(預設),超過長度就刪除前面的

不適用庫函式,手動實現:

這裡為了方便,規定頭部存放剛剛訪問的元素。

# 雙向鍊錶節點

class

dlinkednode()

:def

__init__

(self)

: self.key =

0 self.val =

0 self.pre =

none

# 指向前乙個節點

self.

next

=none

# 指向後乙個節點

class

lrucache()

:def

__init__

(self,capacity)

: self.cache =

# hashtabel,用於快速查詢

self.size =

0# 記錄實時長度

self.capacity = capacity # 記錄容量

self.head,self.tail = dlinkednode(

),dlinkednode(

)# 頭結點和尾**

self.head.

next

= self.tail # 初始化互相連線

self.tail.pre = self.head

def_add_node

(self,node)

:# 在頭結點後面插入乙個新節點

node.pre = self.head # 每次在頭結點後面插入

node.

next

= self.head.

next

self.head.

next

.pre = node

self.head.

next

= node

def_remove_node

(self,node)

:#刪除當前節點,在屬性中記錄的值中先找到前乙個和後乙個

pre = node.pre

new = node.

next

pre.

next

= new

new.pre = pre

def_move_to_head

(self,node)

:# 直接刪除當前節點,再在頭部新增

self._remove_node(node)

self._add_node(node)

def_pop_tail

(self)

:# 返回當前節點,並刪除

ans = self.tail.pre

self._remove_node(ans)

return ans

defget(self,key)

:# 不存在返回-1,存在則移動到頭部

node = self.cache.get(key,

none)if

not node:

return-1

self._move_to_head(node)

return node.val

defput(self,key,value)

:# 存在則修改,並移動到頭部

# 不存在則在hashtable和鍊錶中新增

node = self.cache.get(key,

none)if

not node:

newnode = dlinkednode(

) newnode.key = key

newnode.val = value

self.cache[key]

= newnode

self._add_node(newnode)

self.size+=

1if self.size>self.capacity:

# 超長,彈出尾部元素

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 如果金鑰不存在,則寫入其資料值。...