既然 get 和 put 需要 O(1) 的時間完成,get 很明顯就是用 Map,put 的話則是 DoubleLinkedList 可以做到!至於怎麼儲存 LRU 和 MRU,其實很簡單,只要每次 get 和 put 都重新放入 list 的最右邊,那最左邊就一定是 LRU,因為會被擠到最左邊去。
classLRUCache{privateMap<Integer,Node> cache;privateint capacity;privateNode left;privateNode right;publicLRUCache(int capacity){this.capacity = capacity;
cache =newHashMap<>();// Init. LRU and MRUthis.left =newNode(0,0);// dummy nodethis.right =newNode(0,0);// dummy nodethis.left.next =this.right;// Real LRUthis.right.prev =this.left;// Real MRU}publicintget(int key){if(cache.containsKey(key)){remove(cache.get(key));insert(cache.get(key));// Become MRUreturn cache.get(key).val;}else{return-1;}}publicvoidput(int key,int val){if(cache.containsKey(key)){remove(cache.get(key));}
cache.put(key,newNode(key, val));insert(cache.get(key));// Exceed capacityif(cache.size()> capacity){Node lru =this.left.next;remove(lru);// Remove from list
cache.remove(lru.key);// Remove from map}}privatevoidremove(Node node){// Previous Node of nodeNode prevNode = node.prev;// Next Node of nodeNode nextNode = node.next;
prevNode.next = nextNode;
nextNode.prev = prevNode;}privatevoidinsert(Node node){// New node as the MRUNode prevNode =this.right.prev;// Dummy nodeNode nextNode =this.right;// Point to the new node
prevNode.next = node;
nextNode.prev = node;// New node point to its neighbours
node.prev = prevNode;
node.next = nextNode;}privateclassNode{privateint key;privateint val;Node prev;Node next;publicNode(int key,int val){this.key = key;this.val = val;}}}/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/