# Leetcode 146. LRU Cache
## 題解
### 雙項鍊錶 + 雜湊表
```python=
class DListNode:
def __init__(self, key: int = -1, val: int = -1, prev = None, next = None):
self.key = key
self.val = val
self.prev = prev
self.next = next
class DLinkedList:
def __init__(self):
self.head = DListNode()
self.tail = DListNode()
self.head.next = self.tail
self.tail.prev = self.head
def insert(self, head: DListNode, node: DListNode, tail: DListNode) -> None:
head.next = node
node.prev = head
node.next = tail
tail.prev = node
def insertFirst(self, node: DListNode):
head = self.head
tail = self.head.next
self.insert(head,node,tail)
def insertLast(self, node: DListNode):
head = self.tail.prev
tail = self.tail
self.insert(head,node,tail)
def remove(self, node: DListNode):
head = node.prev
tail = node.next
head.next = tail
tail.prev = head
node.prev = None
node.next = None
def changeToFirst(self, node: DListNode) -> None:
self.remove(node)
self.insertFirst(node)
del node
class LRUCache(DLinkedList):
def __init__(self, capacity: int):
super().__init__()
self.capacity = capacity
self.current_capacity = 0
self.hash_map = {}
@property
def reach_max_capacity(self):
return self.current_capacity > self.capacity
def get(self, key: int) -> int:
if key in self.hash_map:
node = self.hash_map[key]
self.changeToFirst(node)
return node.val
return -1
def put(self, key: int, value: int) -> None:
if key not in self.hash_map:
node = DListNode(key,value)
self.insertFirst(node)
self.hash_map[key] = node
self.current_capacity += 1
if self.reach_max_capacity:
node = self.hash_map[self.tail.prev.key]
del self.hash_map[node.key]
self.remove(node)
del node
self.current_capacity -= 1
else:
node = self.hash_map[key]
node.val = value
self.changeToFirst(node)
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
```
## 參考
https://isdaniel.github.io/lru-algorithm/