思路源自
【面试高频】146. LRU 缓存
采用哈希表+双向链表
put一个键值对时,采用头插法将缓存块置于等级较高的位置,如果put数量超出限制,那么就将尾部的缓存块删除,以此达到置换的一个效果
get一个键值对也是同样的思路,如果不命中直接返回-1,如果命中先删除缓存块再头插缓存块,这样就达到了访问后更新缓存块等级的目的
class LRUCache {class DoubleLinkedNode {DoubleLinkedNode pre;int key;int value;DoubleLinkedNode next;public DoubleLinkedNode() {key=-1;value=-1;}public DoubleLinkedNode(int key, int value) {this.key=key;this.value = value;}}private int size;private int capacity;private Map<Integer,DoubleLinkedNode> cache;DoubleLinkedNode head;DoubleLinkedNode tail;//初始化两个虚拟节点,头尾指针互指public LRUCache(int capacity) {this.size=0;this.capacity=capacity;this.cache = new HashMap<>();this.head = new DoubleLinkedNode();this.tail = new DoubleLinkedNode();head.pre=null;head.next=tail;tail.pre=head;tail.next = null;}//获取缓存中的值,如果命中要更新缓存public int get(int key) {if (cache.containsKey(key)) {DoubleLinkedNode doubleLinkedNode = cache.get(key);this.delete(doubleLinkedNode.key);this.add(doubleLinkedNode.key, doubleLinkedNode.value);return doubleLinkedNode.value;} else {return -1;}}//缓存添加或者置换public void put(int key, int value) {if (cache.containsKey(key)) {this.delete(key);this.add(key, value);} else {if (this.capacity == this.size) {this.delete(tail.pre.key);}this.add(key, value);}}//新增一个新的缓存,采用头插法private void add(int key, int value) {DoubleLinkedNode doubleLinkedNode = new DoubleLinkedNode(key, value);doubleLinkedNode.pre=this.head;doubleLinkedNode.next=this.head.next;this.head.next.pre=doubleLinkedNode;this.head.next=doubleLinkedNode;this.size++;cache.put(key, doubleLinkedNode);}//删除一个现有缓存private void delete(int key) {DoubleLinkedNode doubleLinkedNode = cache.get(key);doubleLinkedNode.pre.next=doubleLinkedNode.next;doubleLinkedNode.next.pre = doubleLinkedNode.pre;this.size--;cache.remove(key);}
}/*** 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);*/