1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
| class LFUCache {
int minfreq; int capacity; Map<Integer, Node> keyTable; Map<Integer,DoublyLinkedList> freqTable; public LFUCache(int capacity) { this.minfreq =0 ; this.capacity = capacity; keyTable = new HashMap<Integer,Node>(); freqTable = new HashMap<Integer,DoublyLinkedList>();
}
public int get(int key) { if (capacity == 0) { return -1; } if (!keyTable.containsKey(key)) { return -1; } Node node = keyTable.get(key); int val = node.val, freq = node.freq; freqTable.get(freq).remove(node); if (freqTable.get(freq).size == 0) { freqTable.remove(freq); if (minfreq == freq) { minfreq += 1; } } DoublyLinkedList list = freqTable.getOrDefault(freq + 1, new DoublyLinkedList()); list.addFirst(new Node(key, val, freq + 1)); freqTable.put(freq + 1, list); keyTable.put(key, freqTable.get(freq + 1).getHead()); return val; }
public void put(int key, int value) { if (capacity == 0) { return; } if (!keyTable.containsKey(key)) { if (keyTable.size() == capacity) { Node node = freqTable.get(minfreq).getTail(); keyTable.remove(node.key); freqTable.get(minfreq).remove(node); if (freqTable.get(minfreq).size == 0) { freqTable.remove(minfreq); } } DoublyLinkedList list = freqTable.getOrDefault(1, new DoublyLinkedList()); list.addFirst(new Node(key, value, 1)); freqTable.put(1, list); keyTable.put(key, freqTable.get(1).getHead()); minfreq = 1; } else { Node node = keyTable.get(key); int freq = node.freq; freqTable.get(freq).remove(node); if (freqTable.get(freq).size == 0) { freqTable.remove(freq); if (minfreq == freq) { minfreq += 1; } } DoublyLinkedList list = freqTable.getOrDefault(freq + 1, new DoublyLinkedList()); list.addFirst(new Node(key, value, freq + 1)); freqTable.put(freq + 1, list); keyTable.put(key, freqTable.get(freq + 1).getHead()); } }
class Node { int key, val, freq; Node prev, next;
Node() { this(-1, -1, 0); }
Node(int key, int val, int freq) { this.key = key; this.val = val; this.freq = freq; } }
class DoublyLinkedList { Node dummyHead, dummyTail; int size;
DoublyLinkedList() { dummyHead = new Node(); dummyTail = new Node(); dummyHead.next = dummyTail; dummyTail.prev = dummyHead; size = 0; }
public void addFirst(Node node) { Node prevHead = dummyHead.next; node.prev = dummyHead; dummyHead.next = node; node.next = prevHead; prevHead.prev = node; size++; }
public void remove(Node node) { Node prev = node.prev, next = node.next; prev.next = next; next.prev = prev; size--; }
public Node getHead() { return dummyHead.next; }
public Node getTail() { return dummyTail.prev; }
}
}
|