*LeetCode--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.
设计最近最久未访问缓存,并实现两个函数get和set,get函数获取一个元素,并更新位置,set添加元素
方法1:使用TreeMap,时间复杂度O(nlogn) ,因为插入TreeMap耗时就是树的高度
//用treemap, 速度很慢. public class LRUCache2 { long timestamp ; int capacity; int currnum ; TreeMap<Long , Integer> tmap ; //存放时间--key HashMap<Integer,Long> hmap_time ; //存放key--时间 HashMap<Integer, Integer> hmap; //存放key--value public LRUCache2(int capacity) { this.capacity = capacity; currnum = 0; tmap = new TreeMap<Long,Integer>(); hmap_time =new HashMap<Integer,Long>(); hmap = new HashMap<Integer,Integer>(); } public int get(int key) { Integer value = hmap.get(key); if(value==null) return -1; long currtime = hmap_time.get(key); tmap.remove(currtime); timestamp++; tmap.put(timestamp, key); hmap_time.put(key, timestamp); System.out.println("get "+hmap_time); return value; } public void set(int key, int value) { timestamp++; if(currnum==capacity&&!hmap.containsKey(key)){ long deltime = tmap.firstKey(); int delkey = tmap.firstEntry().getValue(); tmap.remove(deltime); //删除时间最小的key hmap_time.remove(delkey); //删除key对应的时间 hmap.remove(delkey); //删除key对应的value tmap.put(timestamp, key); hmap_time.put(key,timestamp); hmap.put(key, value); }else{ if(!hmap.containsKey(key)){ currnum++; tmap.put(timestamp, key); hmap_time.put(key,timestamp); hmap.put(key, value); }else{ long currtime = hmap_time.get(key); tmap.remove(currtime); tmap.put(timestamp, key); hmap_time.put(key,timestamp); hmap.put(key, value); } } } }
方法2:使用HashMap和双端队列结合,双端队列控制访问的先后顺序,HashMap用于定位元素
class DLinkedNode { int key; int value; DLinkedNode pre; DLinkedNode post; } public class LRUCache { private HashMap<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>(); private int count; private int capacity; private DLinkedNode head, tail; // 头指针和尾指针 public LRUCache(int capacity) { this.count = 0; this.capacity = capacity; head = new DLinkedNode(); head.pre = null; tail = new DLinkedNode(); tail.post = null; head.post = tail; tail.pre = head; } public int get(int key) { DLinkedNode node = cache.get(key); if (node == null) { return -1; // should raise exception here. } // move the accessed node to the head; this.moveToHead(node); return node.value; } public void set(int key, int value) { DLinkedNode node = cache.get(key); if (node == null) { DLinkedNode newNode = new DLinkedNode(); newNode.key = key; newNode.value = value; this.cache.put(key, newNode); this.addNode(newNode); count++; if (count > capacity) { // pop the tail DLinkedNode tail = this.popTail(); // 删除链表元素 this.cache.remove(tail.key); // 删除value --count; } } else { // update the value. node.value = value; this.moveToHead(node); } } // Always add the new node right after head; private void addNode(DLinkedNode node) { node.pre = head; node.post = head.post; head.post.pre = node; head.post = node; } //Remove an existing node from the linked list. private void removeNode(DLinkedNode node) { DLinkedNode pre = node.pre; DLinkedNode post = node.post; pre.post = post; post.pre = pre; } //Move certain node in between to the head. private void moveToHead(DLinkedNode node) { this.removeNode(node); this.addNode(node); } // pop the current tail. private DLinkedNode popTail() { DLinkedNode res = tail.pre; this.removeNode(res); return res; } }

浙公网安备 33010602011771号