Skip to content

Commit 3db87a7

Browse files
committed
implement lru
1 parent d051a65 commit 3db87a7

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

docs/03_链表/lru_cache.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,83 @@ def test():
132132

133133
if __name__ == '__main__':
134134
test()
135+
136+
137+
######################################### 使用双链表实现 LRUcache ####################################################
138+
"""
139+
一般面试中不会让我们直接用内置结构,所以这里提供一个自己实现的双链表+map lru 缓存。这也是力扣上的一道真题:
140+
[146] LRU 缓存 https://leetcode-cn.com/problems/lru-cache/description/
141+
"""
142+
143+
class ListNode:
144+
def __init__(self, key=None, value=None):
145+
self.key = key
146+
self.value = value
147+
self.prev = self.next = None
148+
149+
150+
class List:
151+
def __init__(self):
152+
"""循环双链表。注意增加了虚拟头尾结点 head,tail 方便处理"""
153+
self.head = ListNode()
154+
self.tail = ListNode()
155+
self.head.prev = self.head.next = self.tail
156+
self.tail.next = self.tail.prev = self.head
157+
158+
def delete_node(self, node): # 删除指定节点
159+
node.prev.next = node.next
160+
node.next.prev = node.prev
161+
162+
def add_to_head(self, node): # 指定节点添加到 self.head 后
163+
nextnode = self.head.next
164+
node.next = nextnode
165+
node.prev = self.head
166+
self.head.next = node
167+
nextnode.prev = node
168+
169+
170+
class LRUCache(object):
171+
172+
def __init__(self, capacity):
173+
"""
174+
思路:循环双链表 + 字典
175+
:type capacity: int
176+
"""
177+
self.map = dict()
178+
self.ll = List()
179+
self.capacity = capacity
180+
181+
def get(self, key):
182+
"""
183+
:type key: int
184+
:rtype: int
185+
"""
186+
if key not in self.map:
187+
return -1
188+
189+
node = self.map[key]
190+
self.ll.delete_node(node)
191+
self.ll.add_to_head(node)
192+
return node.value
193+
194+
def put(self, key, value):
195+
"""
196+
:type key: int
197+
:type value: int
198+
:rtype: None
199+
"""
200+
if key in self.map:
201+
node = self.map[key]
202+
node.value = value # 修改结构体会也会修改 map 对应 value 的引用
203+
self.ll.delete_node(node)
204+
self.ll.add_to_head(node)
205+
else:
206+
if len(self.map) >= self.capacity: # 直接用 len(self.map) ,不需要self.size 字段了
207+
tailnode = self.ll.tail.prev
208+
self.ll.delete_node(tailnode)
209+
del self.map[tailnode.key]
210+
211+
node = ListNode(key, value)
212+
self.map[key] = node
213+
self.ll.add_to_head(node)
214+

0 commit comments

Comments
 (0)