LRU Cache
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 (will 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 reached its capacity, it should invalidate the least recently used item before inserting a new item.
这个题用双向linkedlist最好做,同时用hashtable来方便查找到需要的listnode。最左边的代表最近used的,最右边的代表没有used的。
public class LRUCache { public int capacity, size; public ListNode dummyHead, dummyTail; public Dictionary<int,ListNode> dic; public LRUCache(int capacity) { this.capacity = capacity; size = 0; dummyHead = new ListNode(0, 0); dummyTail = new ListNode(0, 0); dummyTail.prev = dummyHead; dummyHead.next = dummyTail; dic = new Dictionary<int,ListNode>(); } public int Get(int key) { if(dic.ContainsKey(key)) { var node = dic[key]; Remove(node); AddToHead(node); return node.val; } else return -1; } public void Set(int key, int value) { if(dic.ContainsKey(key)) { var node = dic[key]; Remove(node); node.val = value; AddToHead(node); } else { if(size >= capacity) { dic.Remove( dummyTail.prev.key); RemoveLast(); } var newNode = new ListNode(key,value); AddToHead(newNode); dic.Add(key,newNode); size++; } } private void Remove(ListNode node) { if(node == null) return; if(node.prev != null)node.prev.next = node.next; if(node.next != null) node.next.prev = node.prev; } private void RemoveLast() { dummyTail.prev.prev.next = dummyTail; dummyTail.prev = dummyTail.prev.prev; } private void AddToHead(ListNode node) { if(node == null) return; var temp = dummyHead.next; dummyHead.next = node; node.prev = dummyHead; temp.prev = node; node.next = temp; } } public class ListNode { public int key, val; public ListNode prev, next; public ListNode(int k, int v) { key = k; val = v; prev = null; next = null; } }