Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put. get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. put(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. Follow up: Could you do both operations in O(1) time complexity? Example: LRUCache cache = new LRUCache( 2 /* capacity */ ); cache.put(1, 1); cache.put(2, 2); cache.get(1); // returns 1 cache.put(3, 3); // evicts key 2 cache.get(2); // returns -1 (not found) cache.put(4, 4); // evicts key 1 cache.get(1); // returns -1 (not found) cache.get(3); // returns 3 cache.get(4); // returns 4
此题的思路是运用hashmap和double linked nodes
The hash makes the time of get() to be O(1). The list of double linked nodes make the nodes adding/removal operations O(1).
class LRUCache { class Node{ int key; int value; Node pre; Node next; public Node(int key, int value){ this.key = key; this.value = value; } } int capacity; Map<Integer, Node> map = new HashMap<>(); Node head=null; Node end=null; public LRUCache(int capacity) { this.capacity = capacity; } public int get(int key) { if(map.containsKey(key)){ Node n = map.get(key); remove(n); setHead(n); return n.value; } return -1; } public void remove(Node n){ if(n.pre != null){ n.pre.next = n.next; } else{ head = n.next; } if(n.next != null){ n.next.pre = n.pre; } else{ end = n.pre; } } public void setHead(Node n){ n.next = head; n.pre = null; if(head != null){ head.pre = n; } head = n; if(end == null){ end = head; } } public void put(int key, int value) { if(map.containsKey(key)){ Node oldNode = map.get(key); oldNode.value = value; remove(oldNode); setHead(oldNode); } else{ Node newNode = new Node(key, value); if(map.size() >= capacity){ map.remove(end.key); remove(end); setHead(newNode); } else{ setHead(newNode); } map.put(key, newNode); } } } /** * 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); */
class LRUCache { class Node { int key; int value; Node pre; Node next; } int capacity; HashMap<Integer, Node> map; Node head; Node tail; public LRUCache(int capacity) { this.capacity = capacity; this.map = new HashMap<Integer, Node>(); this.head = null; this.tail = null; } public int get(int key) { int v = -1; if(this.map.containsKey(key)){ Node n = this.map.get(key); //remove node from current position remove(n); //insert node to head of the list addToHead(n); v = n.value; } return v; } public void put(int key, int value) { if(map.containsKey(key)){ Node n = map.get(key); n.value = value; remove(n); addToHead(n); } else{ Node n = new Node(); n.key = key; n.value = value; if(this.map.size() == this.capacity){ //remove tail map.remove(this.tail.key); remove(this.tail); } //add new node to head addToHead(n); map.put(key, n); } } public void remove(Node node){ if(node.pre != null){ node.pre.next = node.next; } else{ this.head = node.next; } if(node.next != null){ node.next.pre = node.pre; } else{ this.tail = node.pre; } } public void addToHead(Node node){ node.pre = null; node.next = this.head; if(this.head != null){ this.head.pre = node; } this.head = node; if(this.tail == null){ this.tail = node; } } } /** * 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); */
二刷
转载于:https://www.cnblogs.com/incrediblechangshuo/p/9066074.html