24. LFU缓存
LFU是一个著名的缓存算法
对于容量为k的缓存,如果缓存已满,并且需要逐出其中的密钥,则最少使用的密钥将被踢出。
实现LFU中的set 和 get
样例
输入:
LFUCache(3)
set(2,2)
set(1,1)
get(2)
get(1)
get(2)
set(3,3)
set(4,4)
get(3)
get(2)
get(1)
get(4)
输出:
2
1
2
-1
2
1
4
public class LFUCache {
class Cache {
int val;
long lastTime;
int useNumber;
Cache(int val, long lastTime, int useNumber) {
this.val = val;
this.lastTime = lastTime;
this.useNumber = useNumber;
}
}
HashMap<Integer, Cache> numArray;
int size;
/*
* @param capacity: An integer
*/
public LFUCache(int capacity) {
// do intialization if necessary
size = capacity;
numArray = new HashMap<>(capacity*2, 0.75f);
}
/*
* @param key: An integer
* @param value: An integer
* @return: nothing
*/
public void set(int key, int value) {
// write your code here
if (numArray.containsKey(key)) {
changList(key,value);
} else {
if (numArray.size() >= size) {
delete();
}
Cache cache = new Cache(value, System.nanoTime(), 0);
numArray.put(key, cache);
}
}
/*
* @param key: An integer
* @return: An integer
*/
public int get(int key) {
// write your code here
if (numArray.containsKey(key)) {
int val=numArray.get(key).val;
changList(key,val);
return val;
} else {
return -1;
}
}
private void delete() {
int minCount = Integer.MAX_VALUE;
long getTime = System.nanoTime();
int t = 0;
for (int key : numArray.keySet()) {
Cache node = numArray.get(key);
if (node.useNumber < minCount || (node.useNumber == minCount && node.lastTime < getTime)) {
t = key;
minCount = node.useNumber;
getTime = node.lastTime;
}
}
numArray.remove(t);
}
private void changList(int key,int value) {
Cache cache = numArray.get(key);
if (cache != null) {
cache.val=value;
cache.useNumber++;
cache.lastTime = System.nanoTime();
// numArray.put(key, cache);
}
}
}
这题难点在于对LFU的理解,一个是次数,还有一个是时间,时间非常容易被忽略,记得加上纳秒级的差距判断,这样比较有效。