题目连接java
整体思路,是双向链表和哈希表搭配使用,同时要记录一个LRU的最大容量Capacity。
双向链表尾部记录最新使用过的记录,头部记录的是最久没有使用过的记录。
具体来讲,对于put操做:node
对于get操做:git
完整代码见:程序员
public static class LRUCache { public static class Node { public int key; public int value; public Node last; public Node next; public Node(int key, int value) { this.key = key; this.value = value; } } public static class DoubleLinkedList { public Node head; public Node tail; public DoubleLinkedList() { head = null; tail = null; } public void moveToLast(Node node) { if (tail == node) { return; } if (head == node) { head = node.next; head.last = null; } else { node.last.next = node.next; node.next.last = node.last; } node.last = tail; node.next = null; tail.next = node; tail = node; } public void addLast(Node node) { if (head == null) { head = node; tail = node; } if (tail != null) { tail.next = node; node.last = tail; tail = node; } } } private HashMap<Integer, Node> map; private DoubleLinkedList list; private final int capacity; public LRUCache(int capacity) { this.map = new HashMap<>(); this.list = new DoubleLinkedList(); this.capacity = capacity; } /*["LRUCache","put","put","get","put","get","put","get","get","get"] [[2],[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]] [null,null,null,1,null,2,null,1,3,4]*/ // note get值后,须要把这个值设置为最新的未使用的过的值 public int get(int key) { if (map.containsKey(key)) { Node node = map.get(key); list.moveToLast(node); return node.value; } return -1; } public void put(int key, int value) { if (map.containsKey(key)) { Node old = map.get(key); old.value = value; list.moveToLast(old); } else { if (map.size() == capacity) { map.remove(list.head.key); list.head.value = value; list.head.key = key; map.put(key, list.head); list.moveToLast(list.head); } else { Node node = new Node(key, value); map.put(key, node); list.addLast(node); } } } }
算法和数据结构笔记github