Design a cache includes 2 functions get(key) - Get the value of the key if the key exists in the cache, otherwise return -1. put(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.
get and put are O(1) operations
Use doubleLinkedList and HashMap
A removeNode and addToHead function
A head and tail Node, the recent update note is next to head
Design a data structure supports 2 functions get(key) - Get the value of the key if the key exists in the cache, otherwise return -1. put(key, value) - Set or insert the value if the key is not already present. When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted
get and put are O(1) operations
3 hashMap
values
counts
countToKey>
// cornor case: capacity <= 0
class LFUCache {
// all hashtables, support O(1) add and delete
// key: value
Map<Integer, Integer> values;
// key: count
Map<Integer, Integer> counts;
// count: [keys]
Map<Integer, LinkedHashSet<Integer>> countToSet;
int min, capacity;
public LFUCache(int capacity) {
this.capacity = capacity;
min = 0;
values = new HashMap<>();
counts = new HashMap<>();
countToSet = new HashMap<>();
countToSet.put(1, new LinkedHashSet<Integer>());
}
public int get(int key) {
if(!values.containsKey(key)) return -1;
int count = counts.get(key);
// update counts
counts.put(key, count+1);
// updates countToSet
countToSet.get(count).remove(key);
if(min == count && countToSet.get(count).size() == 0){
min = count+1;
}
if(!countToSet.containsKey(count+1)){
countToSet.put(count+1, new LinkedHashSet<Integer>());
}
countToSet.get(count+1).add(key);
return values.get(key);
}
public void put(int key, int value) {
if(capacity <= 0) return;
if(values.containsKey(key)){
values.put(key, value);
// update counts and countToSet
get(key);
}else{
// 必須先做update的動作, 不然會包含剛更新的資訊
if(values.size() == capacity){
int k = countToSet.get(min).iterator().next();
values.remove(k);
counts.remove(k);
countToSet.get(min).remove(k);
}
min = 1;
values.put(key, value);
counts.put(key, 1);
countToSet.get(1).add(key);
}
}
}
Use DoubleLinkedList and 2 HashMap (see description)