牛客101题
前面都在定义节点,看上去很复杂 其实都是变量,构造函数和需要重写的方法。
四个变量分别是键值对,使用的次数,和组后一次调用的时间,有kv键值对那么get肯定要用hashmap保证时间复杂度为O(1)。
class Solution {
//按照调用次数
class MyNode implements Comparable {
int key;
int val;
int count;
int time;
public MyNode(int key, int val, int count, int time) {
this.key = key;
this.val = val;
this.count = count;
this.time = time;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyNode myNode = (MyNode) o;
return key == myNode.key &&
val == myNode.val &&
count == myNode.count &&
time == myNode.time;
}
@Override
public int hashCode() {
return Objects.hash(key, val, count, time);
}
@Override
public int compareTo(Object o) {
MyNode o2 = (MyNode) o;
return this.count == o2.count ? this.time - o2.time : this.count - o2.count;
}
}
HashMap<Integer, MyNode> hashMap = new HashMap<>();
TreeSet<MyNode> treeSet = new TreeSet<>();
public int[] LFU(int[][] operators, int k) {
ArrayList<Integer> getRes = new ArrayList<>();
int timeRecord = 0;
int size = k;
for (int i = 0; i < operators.length; i++) {
int[] operator = operators[i];
int type = operator[0];
int key = operator[1];
if (type == 1) {//存值
int value = operator[2];
if (hashMap.containsKey(key)) {
MyNode myNode = new MyNode(key, value, hashMap.get(key).count + 1, timeRecord++);
hashMap.put(key, myNode);
treeSet.add(myNode);
} else {
if (size > 0) {
MyNode myNode = new MyNode(key, value, 1, timeRecord++);
hashMap.put(key, myNode);
treeSet.add(myNode);
size--;
} else {
MyNode pollFirst = treeSet.pollFirst();
hashMap.remove(pollFirst.key);
MyNode myNode = new MyNode(key, value, 1, timeRecord++);
hashMap.put(key, myNode);
treeSet.add(myNode);
}
}
} else if (type == 2) {
if (!hashMap.containsKey(key)) {
getRes.add(-1);
} else {//关键好关键
MyNode myNode = hashMap.get(key);
getRes.add(myNode.val);
treeSet.remove(myNode);//先删除再修改再能正常排序
myNode.count++;
myNode.time = timeRecord++;
treeSet.add(myNode);
hashMap.put(key, myNode);
}
}
}
int[] res = new int[getRes.size()];
for (int i = 0; i < getRes.size(); i++) {
res[i] = getRes.get(i);
}
return res;
}
}
这里有个tip:
在type==2 要读取的时候,必须要先删除tresSet的节点,再重新赋值,添加才能正常排序。
MyNode myNode = hashMap.get(key);
getRes.add(myNode.val);
treeSet.remove(myNode);
myNode.count++;
myNode.time = timeRecord++;
treeSet.add(myNode);
hashMap.put(key, myNode);
如果这么写那么结果就是错误的
应该是指针的问题,treeSet内部不会重排。必须要先删除再操作!
MyNode myNode = hashMap.get(key);
getRes.add(myNode.val);
myNode.count++;
myNode.time = timeRecord++;
treeSet.remove(myNode);//写不写都没用
treeSet.add(myNode);//写不写都没用
hashMap.put(key, myNode);