Question
Link
Design and implement a data structure for Least recently Used (LRU) cache. It should support the following operations: get
and set
.
get(key)
-Get The value ('ll always be positive) of the key if the key exists in the cache, otherwise return-1.
set(key, value)
-Set or insert the value if the key is not already present. When the cache is reached its capacity, it should invalidate the least recently used item before inserting a new item.
Stats
Adjusted difficulty |
4 |
Time to use |
Very Difficult |
Ratings/color = 1 (white) 2 (lime) 3 (yellow) 4/5 (red)
Analysis
This was a difficult question, I can ' t write the solution easily even after a month.
Solution
The solution is to use a doubly-linked-list and a HashMap. Doing This allows O (1) Search, remove and insert. A very nice and sophisticated data structure example, and very high frequency in interviews.
2 Important things to note while coding:
We Need 2 helper Methods:removenode () and Setnodeashead ().
Because we reuse both methods for Get () and set () methods.
Initialization of LRU
We need 5 variables:capacity, current size (optional and good to has), HashMap, head, tail. Don ' t forget initialize tail.
Initialization of Doublelinkedlistnode (the key in List are the same as the key in map so we can reference from each other)
This is easy, but does not forget about both key and value variable. We must use Doublelinkedlistnode.key if we want to delete tail.
Code
Public classLRUCache {intsize, capacity; HashMap<integer, doublelink> map =NewHashmap<integer, doublelink>(); Doublelink Head; Doublelink tail; PublicLRUCache (intcapacity) { This. Capacity =capacity; This. Size = 0; This. Head =NULL; This. Tail =NULL; } Public voidRemove (Doublelink node) {if(node = = Head && node = =tail) {Head=NULL; Tail=NULL; }Else if(node = =tail) {Tail.prev.next=NULL; Tail=Tail.prev; }Else{Node.prev.next=Node.next; Node.next.prev=Node.prev; } Node.prev=NULL; Node.next=NULL; } Public voidSethead (Doublelink node) {if(Head! =NULL) {Head.prev=node; Node.next=Head; Node.prev=NULL; Head=node; }Else{//First node insertedHead =node; Tail=node; } } Public intGetintkey) { if(! Map.containskey (key))//Key not found return-1; Doublelink Target=Map.get (key); if(Target! = head) {//if it is already head we don't need to update it.Remove (target); Sethead (target); } returnMap.get (Key). Val; } Public voidSetintKeyintvalue) { if(Get (key)! =-1) {//Update Old nodeDoublelink node =Map.get (key); Node.val=value; if(Node! =head) {Remove (node); Sethead (node); } } Else{//Insert new nodeDoublelink Newhead =NewDoublelink (key, value); if(Size = =capacity) {Map.Remove (Tail.key); Remove (tail); } Elsesize++; Map.put (key, Newhead); Sethead (Newhead); } } classDoublelink {//Doublelinkedlist can delete a node moer easily cause you can use Node.prev to connect Node.next. intVal; intkey; Doublelink Next; Doublelink prev; PublicDoublelink (intKintv) { This. Key =K; This. val =v; } }}
8.12 [Leetcode] 146 LRU Cache