From 1930e31d398817923d87bc63361d0041e1de03dc Mon Sep 17 00:00:00 2001 From: Hamid Gasmi Date: Thu, 7 Jul 2022 08:18:02 -0700 Subject: [PATCH 1/2] #241: implement lru cache part 1 --- 09-problems/lc_146_lru_cache.py | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 09-problems/lc_146_lru_cache.py diff --git a/09-problems/lc_146_lru_cache.py b/09-problems/lc_146_lru_cache.py new file mode 100644 index 0000000..6fcf026 --- /dev/null +++ b/09-problems/lc_146_lru_cache.py @@ -0,0 +1,40 @@ +class LRU_Cache: + def __init__(self, capacity: int): + self.__capacity = capacity + + self.__key_node_dict = {} + self.__key_value_dict = {} + self.__doubly_linked_list = None + + def get(self, key: int) -> int: + val = self.__dict.get(key, -1) + if val == -1: + return -1 + + key_node = self.__key_node_dict[key] + + self.__doubly_linked_list.remove(key_node) + self.__doubly_linked_list.add(key_node) + + return val + + def put(self, key: int, value: int) -> None: + + self.__key_value_dict[key] = value + + if self.__doubly_linked_list.tail.key == key: + return + + key_node = self.__key_node_dict(key, None) + if (key_node): + self.__doubly_linked_list.remove(key_node) + self.__doubly_linked_list.add(key_node) + return + + key_node = Doubly_Linked_Node(key) + if len(self.__key_value_dict) > self.__capacity: + self.__doubly_linked_list.remove(self.__doubly_linked_list.head) + + self.__doubly_linked_list.add(key_node) + self.__doubly_linked_list[key] = key_node + \ No newline at end of file From 0d09819b30f07d0a9dc31d6f28666fe051282206 Mon Sep 17 00:00:00 2001 From: Hamid Gasmi Date: Mon, 11 Jul 2022 06:37:41 -0700 Subject: [PATCH 2/2] #241: implement lru cache --- 09-problems/lc_146_lru_cache.py | 72 ++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/09-problems/lc_146_lru_cache.py b/09-problems/lc_146_lru_cache.py index 6fcf026..782fb86 100644 --- a/09-problems/lc_146_lru_cache.py +++ b/09-problems/lc_146_lru_cache.py @@ -1,40 +1,76 @@ -class LRU_Cache: +class Doubly_Linked_Node: + def __init__(self, key: int): + self.prev = None + self.next = None + self.key = key + +class Doubly_Linked_List: + def __init__(self, head: Doubly_Linked_Node, tail: Doubly_Linked_Node): + self.head = head + self.tail = tail + + def add(self, node: Doubly_Linked_Node): + if self.tail == None: + self.head = node + self.tail = node + + else: + self.tail.next = node + node.prev = self.tail + self.tail = node + + def remove(self, node: Doubly_Linked_Node): + if node == self.head == self.tail: + self.head = None + self.tail = None + + elif node == self.head: + self.head = self.head.next + self.head.prev = None + + elif node == self.tail: + self.tail = self.tail.prev + self.tail.next = None + + elif node.prev and node.next: + node.prev.next = node.next + node.next.prev = node.prev + +class LRUCache: def __init__(self, capacity: int): self.__capacity = capacity self.__key_node_dict = {} self.__key_value_dict = {} - self.__doubly_linked_list = None + self.__linked_list = Doubly_Linked_List(None, None) def get(self, key: int) -> int: - val = self.__dict.get(key, -1) + val = self.__key_value_dict.get(key, -1) if val == -1: return -1 key_node = self.__key_node_dict[key] - self.__doubly_linked_list.remove(key_node) - self.__doubly_linked_list.add(key_node) - + self.__linked_list.remove(key_node) + self.__linked_list.add(key_node) + return val def put(self, key: int, value: int) -> None: self.__key_value_dict[key] = value - if self.__doubly_linked_list.tail.key == key: - return - - key_node = self.__key_node_dict(key, None) + key_node = self.__key_node_dict.get(key, None) if (key_node): - self.__doubly_linked_list.remove(key_node) - self.__doubly_linked_list.add(key_node) - return + self.__linked_list.remove(key_node) + else: + key_node = Doubly_Linked_Node(key) + self.__key_node_dict[key] = key_node + self.__linked_list.add(key_node) - key_node = Doubly_Linked_Node(key) if len(self.__key_value_dict) > self.__capacity: - self.__doubly_linked_list.remove(self.__doubly_linked_list.head) + self.__key_node_dict.pop(self.__linked_list.head.key) + self.__key_value_dict.pop(self.__linked_list.head.key) + self.__linked_list.remove(self.__linked_list.head) - self.__doubly_linked_list.add(key_node) - self.__doubly_linked_list[key] = key_node - \ No newline at end of file + \ No newline at end of file