class Node { public int key, val; public Node next, prev; public Node(int k, int v) { this.key = k; this.val = v; }}class DoubleList { private Node head, tail; private int size; public void addFirst(Node node) { if (head == null) { head = tail = node; } else { Node h = head; h.prev = node; node.next = h; head = node; } size++; } public void remove(Node node) { if (head == node && tail == node) { head = null; tail = null; } else if (tail == node) { node.prev.next = null; tail = node.prev; node.prev = null; } else if (head == node) { node.next.prev = null; head = node.next; node.next = null; } else { node.prev.next = node.next; node.next.prev = node.prev; node.next = null; node.prev = null; } size--; } public Node removeLast() { Node node = tail; remove(tail); return node; } public int size() { return size; }}class LRUCache { private HashMap<Integer, Node> map; private DoubleList doubleList; private int cap; public LRUCache(int capacity) { this.cap = capacity; map = new HashMap<>(); doubleList = new DoubleList(); } public int get(int key) { if (!map.containsKey(key)) return -1; Node node = map.get(key); int val = node.val; doubleList.remove(node); doubleList.addFirst(node); return val; } public void put(int key, int val) { Node x = new Node(key, val); if (map.containsKey(key)) { doubleList.remove(map.get(key)); } else { if (cap == doubleList.size()) { Node last = doubleList.removeLast(); map.remove(last.key); } } doubleList.addFirst(x); map.put(key, x); }}