题目原型:
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是Least Recently Used 近期最少使用算法。在操作系统中,我们计算时,假如此时访问一个内存单元,那么我们把这个内存单元的标记加1,然后把其他的内存单元标记减1,当cache满时,我们替换标记值最小的单元。下面看个例子:
首先,1加进来,flag1=1;2加进来,flag2=1,flag1-1=0;2加进来,flag3=1,flag2-1=0,flag1-1=-1;此时4加进来,cache满了,我们替换最小的flag1,那么就是把4放到1的位置上去,以此类推;
代码如下:
Input: 2,[set(2,1),set(1,1),get(2),set(4,1),get(1),get(2)]
Expected: [1,-1,1]
public class LRUCache { private HashMap<Integer, Node> map = new HashMap<Integer, Node>(); private int capacity; private Node head = new Node(0, 0); private Node tail = new Node(0, 0); public LRUCache(int capacity) { this.capacity = capacity; head.next = tail; tail.pre = head; } //相当于访问,所以要重新调整链表的次序,使得刚才被访问的节点放在头结点后 public int get(int key) { if(!map.containsKey(key)) return -1; Node current = map.get(key); current.next.pre = current.pre; current.pre.next = current.next; add(current);//重新调整链表顺序 return current.value; } //插入,如果cache中存在了,则调整链表次序,此时有可能value不能,则需要更新value值;否则,如果容量满了,则应删除最不常访问的节点,然后再添加。 public void set(int key, int value) { //如果已经存在 if(map.containsKey(key)) { Node current = map.get(key); current.value = value; current.next.pre = current.pre; current.pre.next = current.next; add(current);//重新调整链表顺序 } else { if(map.size()==this.capacity) delete(); Node current = new Node(key, value); add(current); map.put(key, current); } } public void add(Node current) { current.next = head.next; head.next.pre = current; head.next = current; current.pre = head; } public void delete() { Node temp = tail.pre; tail.pre = temp.pre; temp.pre.next = tail; temp.next = null; temp.pre = null; map.remove(temp.key); } } class Node { public Node pre = null; public int key; public int value; public Node next = null; Node(int key, int value) { this.key = key; this.value = value; } }