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.
链表题系列的最后一道题,要求设计一种在操作系统中用到的LRU Cache,核心思路是使用HashMap和双向链表来实现节点的开始查找以及删除和插入。注意一些小细节不要形成环或者节点为null。
public class LRUCache { public class CacheNode { int key, val; CacheNode prior, next; public CacheNode(int key, int val) { this.key = key; this.val = val; prior = null; next = null; } } CacheNode head, tail; int size, capacity; HashMap<Integer, CacheNode> map; // fast look up for a specific node public LRUCache(int capacity) { head = new CacheNode(0, 0); tail = head; size = 0; this.capacity = capacity; map = new HashMap<Integer, CacheNode>(); } public int get(int key) { if(map.containsKey(key) == false) { return -1; } else { update(map.get(key)); return map.get(key).val; } } public void set(int key, int value) { if(map.containsKey(key) == true) { CacheNode node = map.get(key); node.val = value; update(node); map.put(key, node); } else { CacheNode node = new CacheNode(key, value); add(node); map.put(key, node); } } private void update(CacheNode node) { // put the node at the back of a list if(node == tail) return; // be careful with corner case node.prior.next = node.next; node.next.prior = node.prior; node.prior = tail; tail.next = node; node.next = null; tail = node; } private void add(CacheNode node) { if(size < capacity) { tail.next = node; node.prior = tail; tail = node; size++; } else { if(head.next == null) return; if(tail == head.next) tail = head; // be careful with corner case map.remove(head.next.key); // remove the head of the list head.next = head.next.next; if(head.next != null) head.next.prior = head; tail.next = node; node.prior = tail; tail = node; } } }
没有评论:
发表评论