題目出處
難度
Medium
個人範例程式碼 - 2022/6/19 二刷
class Node:
def __init__(self,key, val):
self.key = key
self.val = val
self.next = None
self.prev = None
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.hash = {}
self.head = Node(-1, -1)
self.tail = Node(-1, -1)
self.head.next = self.tail
self.tail.prev = self.head
def get(self, key: int) -> int:
if key not in self.hash:
return -1
node = self.hash[key]
self.remove_node(node)
self.move_to_tail(node)
return node.val
def put(self, key: int, value: int) -> None:
if self.get(key) != -1: # old key
self.hash[key].val = value
return
# new key
if len(self.hash) >= self.capacity:
self.pop_front()
node = Node(key, value)
self.move_to_tail(node)
self.hash[key] = node
def remove_node(self, node):
node.prev.next = node.next # remove front-> node
node.next.prev = node.prev # remove node -> next
def move_to_tail(self, node):
node.prev = self.tail.prev # tail.prev <- node
node.next = self.tail # node -> tail
node.prev.next = node # tail.prev -> node
self.tail.prev = node # node <- tail
def pop_front(self):
del self.hash[self.head.next.key]
self.head.next = self.head.next.next
self.head.next.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)
最近在練習程式碼本身就可以自解釋的 Coding style,可以嘗試直接閱讀程式碼理解
算法說明
在標準的解答中,大概念是我們要設計一個 Linked List 配合 hashtable 進行 node 的快速查找,
我們可以把功能進行拆分,大致上我們會需要:
- get:(取得新元素,題目需要)
- put:(加入新元素,題目需要)
- remove_node:移除一個元素 node
- move_to_tail:將一個元素新增至 tail
- pop_front:處理當 capacity 滿的時候,將最舊的元素移除
而為了快速且方便的能在 Linked List 中移動,
我們使用雙向的 Linked List,這樣在「查找前面一個元素」時,會非常方便
input handling
此題為程式設計類題目,需要能夠保持不斷的運作
(並非單純輸入一個 testcase 得到一個結果的類型。)
Boundary conditions
此題為程式設計類題目,需要能夠保持不斷的運作
(並非單純輸入一個 testcase 得到一個結果的類型。)
個人範例程式碼 - 2022/5/18 一刷
有解出來,但不是題目要的 (queue + hashtable)
class LRUCache: # recently
def __init__(self, capacity: int):
self.capacity = capacity
self.hashtable = {}
self.queue = deque()
def get(self, key: int) -> int:
if key not in self.queue:
return -1
value = self.hashtable[key]
self.queue.remove(key)
self.queue.append(key)
# print(self.queue)
return value
def put(self, key: int, value: int) -> None:
if key in self.queue:
self.queue.remove(key)
self.queue.append(key)
self.hashtable[key] = value
if len(self.queue) > self.capacity:
key = self.queue.popleft()
# del self.hashtable[key]
# print(self.queue)
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
最近在練習程式碼本身就可以自解釋的 Coding style,可以嘗試直接閱讀程式碼理解
算法說明
LRU cache 的設計方式,主要是由 linked list + hashtable
概念就是透過 linked list 保持順序性,而透過 hashtable 去查詢。
input handling
此題為程式設計類題目,需要能夠保持不斷的運作
(並非單純輸入一個 testcase 得到一個結果的類型。)
Boundary conditions
此題為程式設計類題目,需要能夠保持不斷的運作
(並非單純輸入一個 testcase 得到一個結果的類型。)