Implement An LRU Cache - The LRU Cache Eviction Policy ("LRU Cache" on LeetCode)

Back To Back SWE · Beginner ·⚡ Algorithms & Data Structures ·7y ago

Key Takeaways

This video teaches how to implement an LRU Cache using the LRU Cache eviction policy as seen on LeetCode

Full Transcript

[Music] alright so in this video today we are going to talk about an apparent Microsoft question I don't know if other companies ask this but implement and LRU cache so first off let's get started with terminology what is LRU and what is a cache LRU stands for at least recently used it is a cache eviction policy when we have a loose collection of items and we want to remove items in a certain order a restricted order remember how we have LIFO first at the last item to go in is the first item to come out for a queue the first item to come in is the first item to come out the least recently used if a similar policy to the FIFO policy except it's you where you can get point of cash so here's an example say we have one two three four in a cache and it is sized for say I want to add another item zero so let me add zero so when we add zero we add it to the front of the cache what this shows is the temporal order of access to items access this item most recently this height of second most recently this item third most recently and what happens is this cache is restricted to a size of four a capacity of four it is a five we need to evict an item and what we understand is that our eviction policy is using the least recently used what is the least recently used item the least recently used item is four so what we do is we evict four from the cap and so now this is our new cache this is our new order of items and now let's access item number two and see what happens so what happens when we access to is that abuse to the front of our cache it is the most accessed item so what you notice is when we access an item used to the front of the list when we go over in size we need to remove an item we ruined at least recently used where will the item be is going to be at the tail of our list the end of our list and the verb I'm using is starting to hints to you the kind of data structures we'll use we'll get into that soon what is it cash you probably are familiar with this if you already are watching this a cash is just something that stores computations so that look up later can be served very quickly and not just computations but also it can store redundant data so that we have quick access to it instead of reaching out to the database instantly it could be many things but the whole point is to speed up future requests for whatever resources that are being asked for what is it LRU cache now now that we've covered LRU we cover in the cache so an LRU cache is a cache will often have a finite capacity and we use the LRU cache eviction policy now let's see our constraints and see how that hints to us how we're going to solve this problem so now imagine getting this problem in an interview and you don't really know what data structures you're going to use you don't really know how we're going to approach this problem let's just look at the requirements that are asked of us we need to support an API of two functions we need to support a get operation which is where we get an item from our cache and we need to support a put operation where we add an item to the front of the cache and we evict the least used item if we hit capacity if we've in capacity and we're going to use the LRU eviction policy if we go over capacity we're gonna remove the least used item keep in mind we're going to need to know where what where that item is we need facts fast access to it we need to be able to get an item in constant time and we need to put an item in constant time these are our constraints for time complexity for space complexity we can go heavy with it and you'll see that this is kind of a space heavy approach which with event space here are the two things we need we need fast look ups and we need backs removals and if you've taken a data structures class have you've done any study on this you might be getting a light bulb in your hand right now when we reduce it to these constraints we know we need these things from this structure we're being asked to build so fast look ups what data structure can help us with that I think great thing my brain goes to is a hash table whatever we're trying to do fast lookups hash tables will allow us to use a set of keys where we can hash them and have fast lookups based on those keys and our hash function that we define we want fast lookups hash table okay but there's another problem how are we going to know where the least recently used item is the last item and how are we going to remove items quickly how are we going to do that maybe we could use a binary search tree that has elevate search time maybe we could use some other structure like an array so just start thinking through data structures in your head another thing that comes fast to my mind when I think of fast removals I think of a doubly linked list and this is for two reasons one if we have instant access to a doubly linked list node we can remove it in constant time because I can touch my next node I can touch my previous node and I can remove myself if it were a singly linked list I won't have access to my previous and it would take all event time to find my previous okay so doubly linked list that makes sense we're going to be able to remove in constant time and another thing is we're going to be able to prevent ourselves from having to resize an array if we use the linear structure like an array for this if we remove an item we need to shift all the elements over with a linked list it's just an abstraction of pointers and we don't need to shift items so it prevents us from doing linear work during resizing because we we don't need to resize a linked list it's an abstraction of pointers between objects doubly linked list looks very good for this problem and a hash table looks very good for this problem and what you'll notice is this is a Araki pattern backing up a special data structure with the properties that we want backing it up with a hash table for fast access into that special property data structure so say we use a binary search tree but we don't want to spend all of each time searching we can back it up with a hash table so always keep this in mind that a hash table is very nice for fast lookups on a special property data structure our special data structure here is our doubly linked list and our hash table is our fast lookup thing that backs us up so now look at the approach you're going to take alright so what we're going to do is we're going to use a doubly linked list backed by a hash table we're going to run through a list of actions whatever we choose a node understand that a hash table is backing that fast lookup if we didn't have the hash table we would potentially do all event operations to find an item but we're just going to act as if we have a hash table to back us up and we're gonna walk through an example and also the code is in the description it is not my code but I heavily commented and reformatted someone else's code to make it very very understandable and internalized Abul so that is in the description so let's walk through this example alright so we're going to walk through this list of actions remember we have constant I'm forget and in constant time for put operation the overall space we're going to use is all of n where n is the capacity we're going to evicted item if it goes over capacity and we're going to be storing an item so this is a space happy thing but at the same time to get fast look ups and fast flip operation so let's begin our capacity is 5 if we go over capacity we have vikt the least recently used item so what we're going to do is we're going to put 1 1 the key of 1 the value of 1 we're going to put that in our list so before we start anything we want to initialize our list with a dummy head and a dummy tail pointer so this is our initialize list we have a dummy head and a dummy tail or capacity is 5 our size is 0 right now what we're going to do is we're going to put the key of 1 and the value of 1 so we're going to put that into the list okay so now we have inserted 1 into the list and now our nesic it next command is put to 3 so let's insert to 3 into the list ok and now we had inserted to 3 so notice when we insert an item it goes to the front of the cache it is the most recently added or accessed item which is at the front and he notice the items that haven't been touched will slowly float towards the back and they're eventually going to be evicted we have these two eye so now let's add 3/4 okay so now we just added 3/4 again 3/4 goes to the front of our cache and now we have 3 4 2 3 1 1 and notice that the top-left corner is our keys and the sting inside is our value we look up by the keys so just keep that in mind so now we're going to add the item 4 7 so let's add 4 7 now we have added the item 4 7 again we added it to a front of our cache we have 4 key the key for key 3 key to key 1 this is our list and now we need to add 6 10 okay and now we've inserted the item to the front of our list notice when we put an item if it already exists we just update the value we have it add any values keys that already existed so we just add them to the list add it to the front of our list and now we have a get operation so we're going to get the value with the key 1 so we're going to retrieve this item and our hash table will allow us to do this in constant time we're gonna have instant access into our list without having to start from the front and traverse all the way up to the key 1 we can retrieve this item and it's going to move to the front of the list because it's just then access okay so we just access one one who is at a tail a borderless we move it to the front of our list we have constant time insertion and deletion from our list or constant time removal and then replacement in our list and we also are able to quickly find an item with our hash table so now we've done this and now we need to get to the item with the key 3 doesn't exist and yes it does we know it exists in constant time so we move this to the front of our list okay so we just accessed three four and now reduce to the front of our list item with the key 3 so now yeah this is this we still are at capacity five we have not needed to exercise our addiction policy so our next operation is we need to put 1 5 we notice that this is the key already in the list so since it is already in the list we're just going to update its values but every time we interact with a node whether we update its value the foot or we get it we need to move it to the front of the list because it was just interactive anytime you interact with a node it was the front of the list so let's move this to the front all right so we updated the value of the note of the key 1 and we moved it to the front of our list the thing is you see these keys but in reality the hash table would be keeping the keys the notes would just be their nodes with their values we wouldn't need to keep the keys on their nodes we could but the hash tables job is to keep the keys this is just for demonstration purposes now we need to look the item 12 7 does that exist in the list no but does not is going to move to the front but we're going to go over capacity we're going to go over the capacity of 5 so we're going to need to evicted item what item do we evict we remove the last item the least recently used item which is sitting at the end of our list so we're going to have instant access to that item so we could just remove this item and then we're going to add this to the front of our list so let's do that so now we have just added the other 12 with the key 12 with the value 7 we've added it to the front of our list we are still at capacity 5 where then we're within capacity so we're going to put 5 to does 5 already exist in our list no it does not we're going to add it to the front we're going to remove our last entry which is the least recently used item we added the item we added the item to the front of our list and now we're still within capacity and now we perform our last operation and we're going to get the item with a key of 4 but the problem is notice that we just removed the item with the key of 4 so we're going to either return null return minus 1 whatever we want to do to signify an empty state and we are basically if finish we can't get the item 4 because it just was removed so this is how the LRU cache works this is what happens whenever we interact with an item that goes to the front of the list we want to remove the least recently Center entry and this kind of a temporal order of the usage of items and is very useful for certain things and remember the code is in the description I have commented every single line of that code walk through that code look through it it's very intuitive it follows the same as our example and really let that let it internalize these concepts so it's in the description go check that out basically this is the video if you like this video hit the like button subscribe to the channel I'm trying to do videos like this every day to help prepare other engineers for the interview that's what this is about so [Music]

Original Description

Code - https://backtobackswe.com/platform/content/implement-an-lru-cache/solutions Free 5-Day Mini-Course: https://backtobackswe.com Try Our Full Platform: https://backtobackswe.com/pricing 📹 Intuitive Video Explanations 🏃 Run Code As You Learn 💾 Save Progress ❓New Unseen Questions 🔎 Get All Solutions Question: Implement an LRU Cache. It is a cache replacement policy that says to evict the least recently used item in the cache. Every time an item is used it goes to the "front" of the cache since it has been used and has priority. Items that are not used will go to the "end" of the cache eventually and get evicted since they are the least used items, they never got a bump up by being used. Additional Cache Eviction Policies: https://en.wikipedia.org/wiki/Cache_replacement_policies What is a Cache? A cache is a hardware or software component that stores data so that future requests for that data can be served faster; the data stored in a cache might be the result of an earlier computation or a copy of data stored elsewhere. What Is An LRU Cache? So a LRU Cache is a storage of items so that future access to those items can be serviced quickly and an LRU policy is used for cache eviction. The Constraints/Operations Lookup of cache items must be O(1) Addition to the cache must be O(1) The cache should evict items using the LRU policy The Approach There are many ways to do this but the most common approach is to use 2 critical structures: a doubly linked list and a hashtable. Our Structures Doubly Linked List: This will hold the items that our cache has. We will have n items in the cache. This structure satisfies the constraint for fast addition since any doubly linked list item can be added or removed in O(1) time with proper references. Hashtable: The hashtable will give us fast access to any item in the doubly linked list items to avoid O(n) search for items and the LRU entry (which will always be at the tail of the doubly linked li
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Back To Back SWE · Back To Back SWE · 17 of 60

1 4 Tips To Learn Java Programming As Fast As Possible As A Beginner
4 Tips To Learn Java Programming As Fast As Possible As A Beginner
Back To Back SWE
2 3 Mistakes Beginners Make When First Learning Java and Android Development
3 Mistakes Beginners Make When First Learning Java and Android Development
Back To Back SWE
3 How To Get A Job At Google | The Ultimate Guide To Algorithmic/Coding Interviews
How To Get A Job At Google | The Ultimate Guide To Algorithmic/Coding Interviews
Back To Back SWE
4 The Ultimate Big O Notation Tutorial (Time & Space Complexity For Algorithms)
The Ultimate Big O Notation Tutorial (Time & Space Complexity For Algorithms)
Back To Back SWE
5 Total Occurrences Of K In A Sorted Array (Facebook Software Engineering Interview Question)
Total Occurrences Of K In A Sorted Array (Facebook Software Engineering Interview Question)
Back To Back SWE
6 The N Queens Problem using Backtracking/Recursion - Explained
The N Queens Problem using Backtracking/Recursion - Explained
Back To Back SWE
7 Compute All Mnemonics For A Phone Number (Recursion/Backtracking Problem)
Compute All Mnemonics For A Phone Number (Recursion/Backtracking Problem)
Back To Back SWE
8 How To Reverse A Singly Linked List | The Ultimate Explanation (Iteratively & Recursively)
How To Reverse A Singly Linked List | The Ultimate Explanation (Iteratively & Recursively)
Back To Back SWE
9 Depth First & Breadth First Graph Search - DFS & BFS Graph Searching Algorithms
Depth First & Breadth First Graph Search - DFS & BFS Graph Searching Algorithms
Back To Back SWE
10 The 0/1 Knapsack Problem (Demystifying Dynamic Programming)
The 0/1 Knapsack Problem (Demystifying Dynamic Programming)
Back To Back SWE
11 The Dutch National Flag Problem (The Quicksort "Band-Aid")
The Dutch National Flag Problem (The Quicksort "Band-Aid")
Back To Back SWE
12 Test If A Binary Tree Is Symmetric ("Symmetric Tree" on Leetcode)
Test If A Binary Tree Is Symmetric ("Symmetric Tree" on Leetcode)
Back To Back SWE
13 The IP Address Decomposition Problem - Compute All Valid IP Addresses From Raw IP String
The IP Address Decomposition Problem - Compute All Valid IP Addresses From Raw IP String
Back To Back SWE
14 How To Permute A String - Generate All Permutations Of A String
How To Permute A String - Generate All Permutations Of A String
Back To Back SWE
15 The Balanced Parentheses Problem - Classic Stack Problem ("Valid Parentheses" on Leetcode)
The Balanced Parentheses Problem - Classic Stack Problem ("Valid Parentheses" on Leetcode)
Back To Back SWE
16 Knuth–Morris–Pratt (KMP) Pattern Matching Substring Search -  First Occurrence Of Substring
Knuth–Morris–Pratt (KMP) Pattern Matching Substring Search - First Occurrence Of Substring
Back To Back SWE
Implement An LRU Cache - The LRU Cache Eviction Policy ("LRU Cache" on LeetCode)
Implement An LRU Cache - The LRU Cache Eviction Policy ("LRU Cache" on LeetCode)
Back To Back SWE
18 Find The Longest Increasing Subsequence - Dynamic Programming Fundamentals
Find The Longest Increasing Subsequence - Dynamic Programming Fundamentals
Back To Back SWE
19 Generate All Palindromic Decompositions Of A String ("Palindrome Partitioning" on Leetcode)
Generate All Palindromic Decompositions Of A String ("Palindrome Partitioning" on Leetcode)
Back To Back SWE
20 Implement A Sudoku Solver - Sudoku Solving Backtracking Algorithm ("Sudoku Solver" on LeetCode)
Implement A Sudoku Solver - Sudoku Solving Backtracking Algorithm ("Sudoku Solver" on LeetCode)
Back To Back SWE
21 Merge K Sorted Arrays - Min Heap Algorithm ("Merge K Sorted Lists" on LeetCode)
Merge K Sorted Arrays - Min Heap Algorithm ("Merge K Sorted Lists" on LeetCode)
Back To Back SWE
22 Partition To K Equal Sum Subsets From An Array of Integers - The Backtracking Approach
Partition To K Equal Sum Subsets From An Array of Integers - The Backtracking Approach
Back To Back SWE
23 Edit Distance Between 2 Strings - The Levenshtein Distance ("Edit Distance" on LeetCode)
Edit Distance Between 2 Strings - The Levenshtein Distance ("Edit Distance" on LeetCode)
Back To Back SWE
24 Total Ways To Decode A String - Recursive Dynamic Programming Approach ("Decode Ways" on LeetCode)
Total Ways To Decode A String - Recursive Dynamic Programming Approach ("Decode Ways" on LeetCode)
Back To Back SWE
25 The Change Making Problem - Fewest Coins To Make Change Dynamic Programming
The Change Making Problem - Fewest Coins To Make Change Dynamic Programming
Back To Back SWE
26 Compute The Next Permutation of A Numeric Sequence - Case Analysis ("Next Permutation" on Leetcode)
Compute The Next Permutation of A Numeric Sequence - Case Analysis ("Next Permutation" on Leetcode)
Back To Back SWE
27 Count Total Unique Binary Search Trees - The nth Catalan Number (Dynamic Programming)
Count Total Unique Binary Search Trees - The nth Catalan Number (Dynamic Programming)
Back To Back SWE
28 Generate All Strings With n Matched Parentheses - Backtracking ("Generate Parentheses" on LeetCode)
Generate All Strings With n Matched Parentheses - Backtracking ("Generate Parentheses" on LeetCode)
Back To Back SWE
29 Implement A Max Stack - A Stack With A .max() API (Similar To "Min Stack" on LeetCode)
Implement A Max Stack - A Stack With A .max() API (Similar To "Min Stack" on LeetCode)
Back To Back SWE
30 The Recursive Staircase - Top Down & Bottom Up Dynamic Programming ("Climbing Stairs" on LeetCode)
The Recursive Staircase - Top Down & Bottom Up Dynamic Programming ("Climbing Stairs" on LeetCode)
Back To Back SWE
31 Search A Maze For Any Path - Depth First Search Fundamentals (Similar To "The Maze" on Leetcode)
Search A Maze For Any Path - Depth First Search Fundamentals (Similar To "The Maze" on Leetcode)
Back To Back SWE
32 Total Unique Ways To Make Change - Dynamic Programming ("Coin Change 2" on LeetCode)
Total Unique Ways To Make Change - Dynamic Programming ("Coin Change 2" on LeetCode)
Back To Back SWE
33 Test If A Binary Tree Is Height Balanced ("Balanced Binary Tree" on LeetCode)
Test If A Binary Tree Is Height Balanced ("Balanced Binary Tree" on LeetCode)
Back To Back SWE
34 Find The Second Largest Item - Heap & Tracking Approach (Beginner Big N Interview Question)
Find The Second Largest Item - Heap & Tracking Approach (Beginner Big N Interview Question)
Back To Back SWE
35 Increment An Integer Represented As An Array ("Plus One" on LeetCode)
Increment An Integer Represented As An Array ("Plus One" on LeetCode)
Back To Back SWE
36 Merge 2 Sorted Lists - A Fundamental Merge Sort Subroutine ("Merge Two Sorted Lists" on LeetCode)
Merge 2 Sorted Lists - A Fundamental Merge Sort Subroutine ("Merge Two Sorted Lists" on LeetCode)
Back To Back SWE
37 Clone An Undirected Graph - The Utility of Hashtable Mappings ("Clone Graph" on Leetcode)
Clone An Undirected Graph - The Utility of Hashtable Mappings ("Clone Graph" on Leetcode)
Back To Back SWE
38 Clone A Linked List (With Random Pointers) - Linear Space Solution & Tricky Constant Space Solution
Clone A Linked List (With Random Pointers) - Linear Space Solution & Tricky Constant Space Solution
Back To Back SWE
39 Deeply Understanding Logarithms In Time Complexities & Their Role In Computer Science
Deeply Understanding Logarithms In Time Complexities & Their Role In Computer Science
Back To Back SWE
40 Implement A Binary Heap - An Efficient Implementation of The Priority Queue ADT (Abstract Data Type)
Implement A Binary Heap - An Efficient Implementation of The Priority Queue ADT (Abstract Data Type)
Back To Back SWE
41 Max Contiguous Subarray Sum - Cubic Time To Kadane's Algorithm ("Maximum Subarray" on LeetCode)
Max Contiguous Subarray Sum - Cubic Time To Kadane's Algorithm ("Maximum Subarray" on LeetCode)
Back To Back SWE
42 Binary Tree Bootcamp: Full, Complete, & Perfect Trees. Preorder, Inorder, & Postorder Traversal.
Binary Tree Bootcamp: Full, Complete, & Perfect Trees. Preorder, Inorder, & Postorder Traversal.
Back To Back SWE
43 What Is Asymptotic Analysis? And Why Does It Matter? A Deeper Understanding of Asymptotic Notation.
What Is Asymptotic Analysis? And Why Does It Matter? A Deeper Understanding of Asymptotic Notation.
Back To Back SWE
44 An In-Depth Algorithmic Analysis of Bubble Sort. Best Case, Average Case, & Worst Case.
An In-Depth Algorithmic Analysis of Bubble Sort. Best Case, Average Case, & Worst Case.
Back To Back SWE
45 Maximum Sum Rectangle In A 2D Matrix - Kadane's Algorithm Applications (Dynamic Programming)
Maximum Sum Rectangle In A 2D Matrix - Kadane's Algorithm Applications (Dynamic Programming)
Back To Back SWE
46 A Detailed Algorithmic Analysis of Insertion Sort. Best Case & Worst Case.
A Detailed Algorithmic Analysis of Insertion Sort. Best Case & Worst Case.
Back To Back SWE
47 Binary Tree Level Order Traversal - Drawing The Parallel Between Trees & Graphs
Binary Tree Level Order Traversal - Drawing The Parallel Between Trees & Graphs
Back To Back SWE
48 Implement A Queue Using Stacks - The Queue ADT ("Implement Queue Using Stacks" on LeetCode)
Implement A Queue Using Stacks - The Queue ADT ("Implement Queue Using Stacks" on LeetCode)
Back To Back SWE
49 All Nodes Distance K In A Binary Tree - Performing Bidirectional Search On A Tree Using A Hashtable
All Nodes Distance K In A Binary Tree - Performing Bidirectional Search On A Tree Using A Hashtable
Back To Back SWE
50 Longest Common Subsequence (2 Strings) - Dynamic Programming & Competing Subproblems
Longest Common Subsequence (2 Strings) - Dynamic Programming & Competing Subproblems
Back To Back SWE
51 Egg Dropping Problem: Dynamic Programming Fundamentals & Understanding Subproblem Decomposition
Egg Dropping Problem: Dynamic Programming Fundamentals & Understanding Subproblem Decomposition
Back To Back SWE
52 Minimum Window Substring: Utilizing Two Pointers & Tracking Character Mappings With A Hashtable
Minimum Window Substring: Utilizing Two Pointers & Tracking Character Mappings With A Hashtable
Back To Back SWE
53 Reverse Polish Notation: Types of Mathematical Notations & Using A Stack To Solve RPN Expressions
Reverse Polish Notation: Types of Mathematical Notations & Using A Stack To Solve RPN Expressions
Back To Back SWE
54 Asymptotic Notations 101: Big O, Big Omega, & Theta (Asymptotic Analysis Bootcamp)
Asymptotic Notations 101: Big O, Big Omega, & Theta (Asymptotic Analysis Bootcamp)
Back To Back SWE
55 The Backtracking Blueprint: The Legendary 3 Keys To Backtracking Algorithms
The Backtracking Blueprint: The Legendary 3 Keys To Backtracking Algorithms
Back To Back SWE
56 Fast Multiplication: From Grade-School Multiplication To Karatsuba's Algorithm
Fast Multiplication: From Grade-School Multiplication To Karatsuba's Algorithm
Back To Back SWE
57 Search A 2D Sorted Matrix - Fundamentals of Search Space Reduction
Search A 2D Sorted Matrix - Fundamentals of Search Space Reduction
Back To Back SWE
58 The Quicksort Sorting Algorithm: Pick A Pivot, Partition, & Recurse
The Quicksort Sorting Algorithm: Pick A Pivot, Partition, & Recurse
Back To Back SWE
59 Lowest Common Ancestor Between 2 Binary Tree Nodes (A Recursive Approach)
Lowest Common Ancestor Between 2 Binary Tree Nodes (A Recursive Approach)
Back To Back SWE
60 Sort A K Sorted Array - Investigating Applications of Min/Max Heaps
Sort A K Sorted Array - Investigating Applications of Min/Max Heaps
Back To Back SWE

Related AI Lessons

Bloom Filters, Explained Properly
Learn how Bloom filters work and their benefits, including tiny memory and blazing speed, in exchange for potential false positives.
Dev.to · Daksh Gargas
Prefix Sums: The Preprocessing Trick That Makes Range Queries Instant
Learn how prefix sums enable instant range queries in arrays, boosting performance in various applications
Medium · Programming
I Thought I Was Ready for the Interview — Then One Simple Math Question Destroyed Me
A simple math question can destroy a developer's interview, highlighting the importance of being prepared for unexpected questions
Medium · Programming
Week 2(Day 10): LeetCode Two Pointers(slow & fast): Remove Duplicates from Sorted Array (Brute…
Learn to remove duplicates from a sorted array using the two pointers technique, improving from brute force to optimized solutions
Medium · Python
Up next
Stump Grinder Carbide Wheel Grinds Hardwood To Chips
Innoforge Studio
Watch →