LRU
根据题意,使用过的数据放在链表的尾部,容量满了就删除链表的头,使用的数据结构是LinkedHashMap。
146. LRU 缓存(中等)
class LRUCache {
private int cap;
private LinkedHashMap<Integer, Integer> list;
public LRUCache(int capacity) {
this.list = new LinkedHashMap<>();
this.cap = capacity;
}
public int get(int key) {
if (!list.containsKey(key)) {
return -1;
}
makeRencentlyUsed(key);
return list.get(key);
}
public void put(int key, int value) {
if (list.containsKey(key)) {
list.put(key, value);
makeRencentlyUsed(key);
return;
}
if (this.cap <= list.size()) {
int oldKey = list.keySet().iterator().next();
list.remove(oldKey);
}
list.put(key, value);
}
private void makeRencentlyUsed(int key) {
int oldValue = list.get(key);
list.remove(key);
list.put(key, oldValue);
}
}
LFU
460. LFU 缓存(困难)
class LFUCache {
private HashMap<Integer, Integer> keyToValue;
private HashMap<Integer, Integer> keyToFreq;
private HashMap<Integer, LinkedHashSet<Integer>> freqToKey;
private int cap;
private int minFreq;
public LFUCache(int capacity) {
this.keyToValue = new HashMap<>();
this.keyToFreq = new HashMap<>();
this.freqToKey = new HashMap<>();
this.cap = capacity;
this.minFreq = 0;
}
public int get(int key) {
if (!keyToValue.containsKey(key)) {
return -1;
}
increaseFreq(key);
return keyToValue.get(key);
}
public void put(int key, int value) {
if (this.cap <= 0) return;
if (keyToValue.containsKey(key)) {
keyToValue.put(key, value);
increaseFreq(key);
return;
}
if (this.cap <= keyToValue.size()) {
removeMinFreq(key);
}
keyToValue.put(key, value);
keyToFreq.put(key, 1);
freqToKey.putIfAbsent(1, new LinkedHashSet<>());
freqToKey.get(1).add(key);
this.minFreq = 1;
return;
}
private void increaseFreq(int key) {
int oldValue = keyToFreq.get(key);
keyToFreq.put(key, oldValue + 1);
freqToKey.get(oldValue).remove(key);
if (freqToKey.get(oldValue).isEmpty()) {
freqToKey.remove(oldValue);
if (minFreq == oldValue) {
minFreq++;
}
}
freqToKey.putIfAbsent(oldValue + 1, new LinkedHashSet<>());
freqToKey.get(oldValue + 1).add(key);
}
private void removeMinFreq(int key) {
LinkedHashSet<Integer> list = freqToKey.get(this.minFreq);
Integer oldKey = list.iterator().next();
list.remove(oldKey);
if (list.isEmpty()) {
freqToKey.remove(this.minFreq);
}
keyToValue.remove(oldKey);
keyToFreq.remove(oldKey);
}
}
|