|
| 1 | +# 146. LRU Cache |
| 2 | +Difficulty: Medium |
| 3 | +Category: HashMap, Doubly Linked List, Design |
| 4 | +Leetcode Link: [Problem Link](https://leetcode.com/problems/lru-cache/) |
| 5 | + |
| 6 | +--- |
| 7 | + |
| 8 | +## 📝 Introduction |
| 9 | + |
| 10 | +Design a data structure that follows the constraints of a Least Recently Used (LRU) cache. |
| 11 | + |
| 12 | +Implement the LRUCache class: |
| 13 | +- LRUCache(int capacity) initializes the LRU cache with a positive size capacity. |
| 14 | +- int get(int key) returns the value of the key if the key exists, otherwise returns -1. |
| 15 | +- void put(int key, int value) updates the value of the key if it exists. Otherwise, adds the key-value pair to the cache. If the number of keys exceeds the capacity, evict the least recently used key. |
| 16 | + |
| 17 | +Both get and put must run in O(1) average time complexity. |
| 18 | + |
| 19 | +--- |
| 20 | + |
| 21 | +## 💡 Approach & Key Insights |
| 22 | + |
| 23 | +To achieve O(1) time complexity for both get and put operations: |
| 24 | +- Use a HashMap to store key → pointer to node in a Doubly Linked List (DLL). |
| 25 | +- The DLL keeps track of the most recently used order, with: |
| 26 | + - Head: Most recently used. |
| 27 | + - Tail: Least recently used. |
| 28 | +- When a key is accessed or added: |
| 29 | + - Move its node to the front (right after head). |
| 30 | + - If capacity is exceeded, remove node from the end (before tail). |
| 31 | + |
| 32 | +--- |
| 33 | + |
| 34 | +## 🛠️ Breakdown of Approaches |
| 35 | + |
| 36 | +### 1️⃣ Brute Force / Naive Approach |
| 37 | + |
| 38 | +Explanation: |
| 39 | +Use a LinkedList and linear search to implement put and get. |
| 40 | +Too slow for O(1) requirement. Every access or insert may require O(N) time for searching. |
| 41 | + |
| 42 | +Time Complexity: O(N) per operation |
| 43 | +Space Complexity: O(N) for storage |
| 44 | + |
| 45 | +Example/Dry Run: |
| 46 | +get(1) — Scan entire list to find key = 1 → O(N) |
| 47 | + |
| 48 | +--- |
| 49 | + |
| 50 | +### 2️⃣ Optimized Approach (HashMap + DLL) |
| 51 | + |
| 52 | +Explanation: |
| 53 | +Use: |
| 54 | +- HashMap<int, Node*> to access nodes in O(1). |
| 55 | +- Doubly Linked List to maintain LRU order. |
| 56 | + |
| 57 | +Steps: |
| 58 | +- get(key): |
| 59 | + - If key exists → move node to head → return value. |
| 60 | + - Else → return -1. |
| 61 | +- put(key, value): |
| 62 | + - If key exists → update value → move node to head. |
| 63 | + - If not → insert new node → add to head. |
| 64 | + - If capacity exceeded → remove node from tail → erase from map. |
| 65 | + |
| 66 | +Time Complexity: O(1) for both get and put |
| 67 | +Space Complexity: O(capacity) |
| 68 | + |
| 69 | +Example/Dry Run: |
| 70 | +Input: |
| 71 | +["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"] |
| 72 | +[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]] |
| 73 | +Output: [null, null, null, 1, null, -1, null, -1, 3, 4] |
| 74 | + |
| 75 | +--- |
| 76 | + |
| 77 | +### 3️⃣ Best / Final Optimized Approach (if applicable) |
| 78 | + |
| 79 | +Same as optimized. No better than O(1) per operation. |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +## 📊 Complexity Analysis |
| 84 | + |
| 85 | +| Approach | Time Complexity | Space Complexity | |
| 86 | +|----------------|------------------|------------------| |
| 87 | +| Brute Force | O(N) | O(N) | |
| 88 | +| Optimized | O(1) | O(N) | |
| 89 | +| Best Approach | O(1) | O(N) | |
| 90 | + |
| 91 | +--- |
| 92 | + |
| 93 | +## 📉 Optimization Ideas |
| 94 | + |
| 95 | +- Use a custom DLL instead of built-in collections for better control over node management. |
| 96 | +- Avoid unnecessary key re-insertion in hashmap. |
| 97 | + |
| 98 | +--- |
| 99 | + |
| 100 | +## 📌 Example Walkthroughs & Dry Runs |
| 101 | + |
| 102 | +Capacity = 2 |
| 103 | +put(1,1) → cache = {1=1} |
| 104 | +put(2,2) → cache = {1=1, 2=2} |
| 105 | +get(1) → return 1 → cache = {2=2, 1=1} |
| 106 | +put(3,3) → evict 2 → cache = {1=1, 3=3} |
| 107 | +get(2) → return -1 (not found) |
| 108 | +put(4,4) → evict 1 → cache = {3=3, 4=4} |
| 109 | +get(1) → return -1 (not found) |
| 110 | +get(3) → return 3 |
| 111 | +get(4) → return 4 |
| 112 | + |
| 113 | +--- |
| 114 | + |
| 115 | + |
| 116 | +## 🔗 Additional Resources |
| 117 | + |
| 118 | +- [Stack Visualization Tool](https://visualgo.net/en/list) |
| 119 | + |
| 120 | +Author: Neha Amin |
| 121 | +Date: 19/07/2025 |
0 commit comments