使用LinkedHashMap,每次调用之后,删除再加入这个K-V,就能保证是最新操作的在前面了。需要注意的是,每次操作put操作需要分成三个类别:1、k已存在;2、k不存在且未达到最大容量;3、k不存在且已经达到最大容量。其中第三种需要找出最少使用且最久的Bolck(笔者在这里没有使用O(lgn)的方法)。这个其实可以用一个minUsedKey来做记录(思路和最小栈一致),这样的话,可以在O(lgn)时间内,感兴趣的读者可以自行实现。
public class Solution {
class Block{
int u;
int k;
int v;
Block(int u,int k,int v){
this.u = u;this.k=k;this.v=v;
}
}
class Cache{
int size;
int maxSize;
Map<Integer,Block> map = new LinkedHashMap<>();
Cache(int maxSize){
this.maxSize = maxSize;
}
public int get(int k){
if(this.map.containsKey(k)){
Block b = this.map.get(k);
b.u+=1;
map.remove(k);
map.put(k,b);
return b.v;
}
else return -1;
}
public void put(int k,int v){
if(map.containsKey(k)){
Block b = map.get(k);
b.v = v;
b.u +=1;
map.remove(k);
map.put(k,b);
}else {
if(this.map.size()<this.maxSize){
this.map.put(k,new Block(1,k,v));
}
else {
List<Block> templist = new ArrayList<>(this.map.values());
int min = templist.get(0).u;
int minKey = templist.get(0).k;
for(int i=1;i<templist.size();++i){
if(templist.get(i).u<min){
minKey = templist.get(i).k;
}
}
this.map.remove(minKey);
this.map.put(k,new Block(1,k,v));
}
}
}
}
public int[] LFU (int[][] operators, int k) {
List<Integer> getOpt =new ArrayList<>();
Cache cache = new Cache(k);
for(int i=0;i<operators.length;++i){
if(operators[i][0]==1){
cache.put(operators[i][1],operators[i][2]);
}else getOpt.add(cache.get(operators[i][1]));
}
int res [] = new int [getOpt.size()];
for(int i=0;i<res.length;++i)res[i] = getOpt.get(i);
return res;
}
}