Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

优化代码, 提升运行效率 #530

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 33 additions & 49 deletions python/06_linkedlist/LRUCache.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Definition for singly-linked list.
class DbListNode(object):
def __init__(self, x, y):
self.key = x
Expand All @@ -8,72 +7,37 @@ def __init__(self, x, y):


class LRUCache:
'''
leet code: 146
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。
它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。
当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间

哈希表+双向链表
哈希表: 查询 O(1)
双向链表: 有序, 增删操作 O(1)

Author: Ben
'''

def __init__(self, capacity: int):
self.cap = capacity
self.hkeys = {}
# self.top和self.tail作为哨兵节点, 避免越界
self.top = DbListNode(None, -1)
self.tail = DbListNode(None, -1)
self.top = DbListNode(None, -1) # top节点的下一个节点是真正的headnode(第一个节点, 头结点)
self.tail = DbListNode(None, -1) # tail一开始充当的是headnode
self.top.next = self.tail
self.tail.prev = self.top

def get(self, key: int) -> int:

if key in self.hkeys.keys():
# 更新结点顺序
cur = self.hkeys[key]
cur = self.hkeys.get(key,None)
if cur:
# 跳出原位置
cur.next.prev = cur.prev
cur.prev.next = cur.next
delete_cur_node(cur)
# 最近用过的置于链表首部
top_node = self.top.next
self.top.next = cur
cur.prev = self.top
cur.next = top_node
top_node.prev = cur

replace_headnode(self, cur)
return self.hkeys[key].val
return -1

def put(self, key: int, value: int) -> None:
if key in self.hkeys.keys():
cur = self.hkeys[key]
cur = self.hkeys.get(key,None)
if cur:
cur.val = value
# 跳出原位置
cur.prev.next = cur.next
cur.next.prev = cur.prev

# 最近用过的置于链表首部
top_node = self.top.next
self.top.next = cur
cur.prev = self.top
cur.next = top_node
top_node.prev = cur
delete_cur_node(cur)
replace_headnode(self, cur)
else:
# 增加新结点至首部
cur = DbListNode(key, value)
self.hkeys[key] = cur
# 最近用过的置于链表首部
top_node = self.top.next
self.top.next = cur
cur.prev = self.top
cur.next = top_node
top_node.prev = cur
self.hkeys[key] = cur # {1 : node}
replace_headnode(self, cur)
if len(self.hkeys.keys()) > self.cap:
self.hkeys.pop(self.tail.prev.key)
# 去掉原尾结点
Expand All @@ -89,6 +53,26 @@ def __repr__(self):
return '->'.join(vals)


def delete_cur_node(cur):
'''
删除当前节点
'''
cur.next.prev = cur.prev
cur.prev.next = cur.next


def replace_headnode(self, cur):
"""
将第一个head node替换为当前节点

cur: 当前节点
"""
top_node = self.top.next # 一开始的是tail
self.top.next = cur # 变成cur
cur.prev = self.top #
cur.next = top_node # top cur tail
top_node.prev = cur # 最开始的headnode的前一个变成了cur

if __name__ == '__main__':
cache = LRUCache(2)
cache.put(1, 1)
Expand All @@ -104,4 +88,4 @@ def __repr__(self):
cache.get(3) # 返回 3
print(cache)
cache.get(4) # 返回 4
print(cache)
print(cache)