leetcode [146]LRU Cache
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.
The cache is initialized with a positive capacity.
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
题目大意:
实现一个LRU结构。
解法:
采用Hashmap+双向链表进行实现,双向链表记录访问次序,HashMap帮助实现时间复杂度为O(1)的查找效率。
java:
class LRUCache { private int capacity; private int count; private DLinkedNode head; private DLinkedNode tail; private Map<Integer,DLinkedNode>cache; class DLinkedNode{ int key; int value; DLinkedNode pre; DLinkedNode next; public DLinkedNode(){ } public DLinkedNode(int key,int value){ this.key=key; this.value=value; this.pre=null; this.next=null; } } public LRUCache(int capacity) { this.count=0; this.capacity=capacity; this.cache=new HashMap<>(); head=new DLinkedNode(); tail=new DLinkedNode(); head.pre=null; tail.next=null; head.next=tail; tail.pre=head; } private void addTohead(DLinkedNode node){ node.next=head.next; head.next.pre=node; node.pre=head; head.next=node; } private void removeNode(DLinkedNode node){ node.next.pre=node.pre; node.pre.next=node.next; node.pre=null; node.next=null; } private void moveToHead(DLinkedNode node){ removeNode(node); addTohead(node); } private void popTail(){ DLinkedNode tmp=tail.pre.pre; tmp.next=tail; tail.pre=tmp; } public int get(int key) { DLinkedNode tmp=cache.get(key); if (tmp!=null){ moveToHead(tmp); return tmp.value; } return -1; } public void put(int key, int value) { if(!cache.containsKey(key)){ DLinkedNode node=new DLinkedNode(key,value); addTohead(node); cache.put(key,node); count++; if (count>capacity){ cache.remove(tail.pre.key); popTail(); count--; } }else{ DLinkedNode tmp=cache.get(key); tmp.value=value; moveToHead(tmp); } } }