Skip to content

Commit 85bc541

Browse files
committed
misc
1 parent 75bdaa5 commit 85bc541

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
class DLLNode:
2+
def __init__(
3+
self,
4+
key: int,
5+
data: int,
6+
prev_node: Optional['DLLNode'] = None,
7+
next_node: Optional['DLLNode'] = None
8+
):
9+
self.key = key
10+
self.data = data
11+
self.prev = prev_node
12+
self.next = next_node
13+
14+
class LRUCache:
15+
def __init__(self, capacity: int):
16+
self.head = None
17+
self.tail = None
18+
self.key2node = {}
19+
self.cap = capacity
20+
self.size = 0
21+
22+
def get(self, key: int) -> int:
23+
if key not in self.key2node :
24+
return -1
25+
26+
output_data = self.pop(key)
27+
self.append_end(key, output_data)
28+
return output_data
29+
30+
def put(self, key: int, value: int) -> None:
31+
if key in self.key2node :
32+
self.pop(key)
33+
34+
if self.size >= self.cap :
35+
self.pop()
36+
37+
self.append_end(key, value)
38+
39+
def append_end(self, key: int, data: int) -> None:
40+
new_node = DLLNode(key=key, data=data, prev_node=self.tail)
41+
self.key2node[key] = new_node
42+
self.size += 1
43+
44+
# this should apply to both if tail and head doesn't exist
45+
# since if at least one node exists, it's both tail and head
46+
if not self.tail :
47+
self.head = new_node
48+
self.tail = new_node
49+
return
50+
51+
self.tail.next = new_node
52+
self.tail = new_node
53+
54+
# Default pop last
55+
def pop(self, key: int = None) -> int :
56+
if self.size == 0 :
57+
return -1
58+
59+
# Pop LFU node by default
60+
if key is None :
61+
key = self.head.key
62+
63+
if key not in self.key2node :
64+
return -1
65+
66+
self.size -= 1
67+
popping_node = self.key2node.pop(key)
68+
output_data = popping_node.data
69+
70+
# If it was the only node in DLL
71+
if self.size == 0 :
72+
self.head = None
73+
self.tail = None
74+
return output_data
75+
76+
# if is head
77+
if popping_node.prev is None :
78+
self.head = popping_node.next
79+
if self.head is not None :
80+
self.head.prev = None
81+
return output_data
82+
83+
# if is tail
84+
if popping_node.next is None :
85+
self.tail = popping_node.prev
86+
if self.tail is not None :
87+
self.tail.next = None
88+
return output_data
89+
90+
# Regular node
91+
prev_node, next_node = popping_node.prev, popping_node.next
92+
prev_node.next, next_node.prev = next_node, prev_node
93+
return output_data
94+
95+
96+
# Your LRUCache object will be instantiated and called as such:
97+
# obj = LRUCache(capacity)
98+
# param_1 = obj.get(key)
99+
# obj.put(key,value)

0 commit comments

Comments
 (0)