DEV Community

tracelit
tracelit

Posted on • Originally published at tracelit.dev

LeetCode 146: Lru Cache — Step-by-Step Visual Trace

Medium — Hash Table | Linked List | Design | Doubly-Linked List

The Problem

Design and implement a data structure for Least Recently Used (LRU) cache that supports get and put operations in O(1) time complexity.

Approach

Use a combination of a hash map for O(1) key lookups and a doubly linked list to maintain insertion order. The hash map stores key-value pairs while the linked list tracks usage order, with most recently used items at the front.

Time: O(1) · Space: O(capacity)

Code

class LRUCache:
    def __init__(self, capacity: int):
        self.capacity = capacity
        self.cache = {}
        self.order = DoublyLinkedList()

    def get(self, key: int) -> int:
        if key in self.cache:
            self.order.move_to_front(key)
            return self.cache[key]
        return -1

    def put(self, key: int, value: int) -> None:
        if key in self.cache:
            self.cache[key] = value
            self.order.move_to_front(key)
        else:
            if len(self.cache) >= self.capacity:
                removed_key = self.order.remove_last()
                del self.cache[removed_key]
            self.cache[key] = value
            self.order.add_to_front(key)

class DoublyLinkedList:
    def __init__(self):
        self.head = ListNode()
        self.tail = ListNode()
        self.head.next = self.tail
        self.tail.prev = self.head
        self.nodes = {}

    def add_to_front(self, key):
        node = ListNode(key)
        node.next = self.head.next
        node.prev = self.head
        self.head.next.prev = node
        self.head.next = node
        self.nodes[key] = node

    def move_to_front(self, key):
        node = self.nodes[key]
        node.prev.next = node.next
        node.next.prev = node.prev
        self.add_to_front(key)

    def remove_last(self):
        node = self.tail.prev
        node.prev.next = self.tail
        self.tail.prev = node.prev
        del self.nodes[node.key]
        return node.key

class ListNode:
    def __init__(self, key=None):
        self.key = key
        self.prev = None
        self.next = None

# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
Enter fullscreen mode Exit fullscreen mode

Watch It Run

TraceLit — See exactly where your code breaks

Paste your LeetCode solution and see every pointer, variable, and data structure update step by step.

favicon tracelit.dev

Open interactive visualization

Try it yourself: Open TraceLit and step through every line.


Built with TraceLit — the visual algorithm tracer for LeetCode practice.

Top comments (0)