题目:
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.
思路:
这个题被问过很多次。感觉是背过了。。很多都是上来让我说说要用什么data structure,然后整体的想法是怎样的。所以脑子里得有个框架。我回答的是当时看大神code ganker提供的解法。用HashMap+Doubled LinkedList,使用这两种数据结构可以使查找与添加删除操作都为O(1)的时间。不说了,直接上代码吧。写的时候出了些错,记录在这里
1 public class LRUCache { 2 class Node { 3 Node pre, next; 4 int key; 5 int val; 6 public Node(int key, int value) { 7 this.key = key; 8 this.val = value; 9 } 10 } 11 12 private int capacity; // 13 private int num; // 14 private HashMap<Integer, Node> map; // 15 private Node first, last; // 16 17 public LRUCache(int capacity) { 18 this.capacity = capacity; 19 num = 0; 20 map = new HashMap<Integer, Node>(); 21 first = null; 22 last = null; 23 } 24 25 public int get(int key) { 26 Node node = map.get(key); 27 if (node == null) { 28 return -1; 29 }else if (node != last) { 30 if (node == first) { 31 first = first.next; 32 }else{ 33 node.pre.next = node.next; 34 } 35 node.next.pre = node.pre; 36 last.next = node; 37 node.pre = last; 38 node.next = null; 39 last = node; 40 } 41 return node.val; 42 } 43 44 public void set(int key, int value) { 45 Node node = map.get(key); 46 if (node != null) { 47 node.val = value; 48 if (node != last) { 49 if (node == first) { 50 first = first.next; 51 }else{ 52 node.pre.next = node.next; 53 } 54 node.next.pre = node.pre; 55 last.next = node; 56 node.next = null; 57 node.pre = last; 58 last = node; 59 } 60 }else{ 61 Node newNode = new Node(key, value); 62 63 //remove element if cache is full 64 if (num >= capacity) { 65 map.remove(first.key);//need provide a key to romve() 66 first = first.next; 67 if (first != null) { 68 first.pre = null; 69 //BUG: need to check first != null first. If it is null, then there is only one element. 70 //then set it to null; 71 }else{ 72 last = null; 73 } 74 num--; 75 } 76 //if there is 0 element in cache. 77 if (first == null && last == null) { 78 first = newNode; 79 last = newNode; 80 }else{ 81 last.next = newNode; 82 newNode.pre = last; 83 last = newNode; 84 } 85 map.put(key, newNode); 86 num++; 87 } 88 } 89 }