460. LFU 缓存
解题思路
- get操作 返回key对应的val 然后增加对应的freq
- 插入操作 如果key已经存在 直接进行更新 如果不存在 但是容器已经满了 直接进行删除freq最小的Key 之后进行插入
class LFUCache {
HashMap<Integer,Integer> keyToVal;
HashMap<Integer,Integer> keyToFreq;
HashMap<Integer,LinkedHashSet<Integer>> freqToKeys;
int minFreq;
int cap;
public LFUCache(int capacity) {
keyToVal = new HashMap<>();
keyToFreq = new HashMap<>();
freqToKeys = new HashMap<>();
this.cap = capacity;
this.minFreq = 0;
}
public int get(int key) {
if(!keyToVal.containsKey(key)){
return -1;
}
increaseFreq(key);
return keyToVal.get(key);
}
public void put(int key, int value) {
if(this.cap <= 0){
return;
}
if(keyToFreq.containsKey(key)){
keyToVal.put(key,value);
increaseFreq(key);
return;
}
if(this.cap <= keyToVal.size()){
removeMinFreqKey();
}
keyToVal.put(key,value);
keyToFreq.put(key,1);
freqToKeys.putIfAbsent(1,new LinkedHashSet<>());
freqToKeys.get(1).add(key);
this.minFreq = 1;
}
private void removeMinFreqKey(){
LinkedHashSet<Integer> keyList = freqToKeys.get(this.minFreq);
int deleteKey = keyList.iterator().next();
keyList.remove(deleteKey);
if(keyList.isEmpty()){
freqToKeys.remove(this.minFreq);
}
keyToVal.remove(deleteKey);
keyToFreq.remove(deleteKey);
}
private void increaseFreq(int key){
int freq = keyToFreq.get(key);
keyToFreq.put(key,freq + 1);
freqToKeys.get(freq).remove(key);
freqToKeys.putIfAbsent(freq + 1,new LinkedHashSet<>());
freqToKeys.get(freq + 1).add(key);
if(freqToKeys.get(freq).isEmpty()){
freqToKeys.remove(freq);
if(freq == this.minFreq){
this.minFreq++;
}
}
}
}