[leedcode 146] LRU Cache
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.
public class LRUCache { //简单的说,cache的存储是一个链表的话,那么只要保证从头到尾的顺序就是cache从新到旧的顺序就好了,对于任何一个节点,如果被访问了,那么就将该节点移至头部。如果cache已满,那么就把尾部的删掉,从头部插入新节点。 //双向链表和hashMap //为了处理简单,当new一个Cache时,需要构造两个head和tail空指针,当保护节点 int capacity; HashMap<Integer,CacheNode> map; CacheNode head; CacheNode tail; class CacheNode{ int key; int value; CacheNode prev; CacheNode next; public CacheNode(int key,int value){ this.key=key; this.value=value; } } public LRUCache(int capacity) { this.capacity=capacity; map=new HashMap<Integer,CacheNode>(capacity); head=new CacheNode(-1,-1);////保护节点 tail=new CacheNode(1,1); head.next=tail; tail.prev=head; } public int get(int key) { if(map.containsKey(key)){//需要更新位置if contains key, just get value and update CacheNode node=map.get(key); moveToHead(map.get(key)); return node.value; }else return -1; } public void set(int key, int value) { if(map.containsKey(key)){//if map contains key, just update value CacheNode node=map.get(key); node.value=value; moveToHead(node); }else if(map.size()<capacity){//not contain & smaller the size CacheNode node=new CacheNode(key,value); moveToHead(node); map.put(key,node); }else{//not contain key and over the size CacheNode node=new CacheNode(key,value); moveToHead(node); map.put(key,node); int index=removeEnd(); map.remove(index); } } public int removeEnd(){ CacheNode node=tail.prev; node.prev.next=tail; tail.prev=node.prev; return node.key; } public void moveToHead(CacheNode node){ if(node.next!=null&&node.prev!=null){//是否节点已经存在于map node.next.prev=node.prev; node.prev.next=node.next; } node.prev=head; node.next=head.next; head.next=node; node.next.prev=node; } }