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
| class LFUCache { class Cache { int key, freq, timestamp; public Cache(int key, int freq, int timestamp) { this.key = key; this.freq = freq; this.timestamp = timestamp; } @Override public boolean equals(Object obj) { return key == ((Cache)(obj)).key; } @Override public int hashCode() { return key; } } int capacity, globalTime; Map<Integer, Integer> cacheMap = null; Map<Integer, Integer> freqMap = null; PriorityQueue<Cache> pq = null; public LFUCache(int capacity) { this.capacity = capacity; globalTime = 0; cacheMap = new HashMap<>(); freqMap = new HashMap<>(); pq = new PriorityQueue<>((c1, c2) -> { return c1.freq == c2.freq? c1.timestamp - c2.timestamp: c1.freq - c2.freq; }); } public int get(int key) { globalTime++; if (cacheMap.containsKey(key)) { update(key); return cacheMap.get(key); } return -1; } public void put(int key, int value) { if (capacity == 0) { return ; } globalTime++; if (cacheMap.containsKey(key)) { update(key); cacheMap.put(key, value); return; } if (cacheMap.size() == capacity) { Cache evict = pq.poll(); cacheMap.remove(evict.key); freqMap.remove(evict.key); } cacheMap.put(key, value); freqMap.put(key, 1); pq.add(new Cache(key, 1, globalTime)); } public void update(int key) { int freq = freqMap.get(key); freqMap.put(key, freq + 1); Cache c = new Cache(key, freq + 1, globalTime); pq.remove(c); pq.add(c); } }
|