题解 | #设计LFU缓存结构#
设计LFU缓存结构
https://www.nowcoder.com/practice/93aacb4a887b46d897b00823f30bfea1
时间复杂度GET和SET都是O(1),空间复杂度O(n),就是有点蛋疼,懒得优化了
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* lfu design
* @param operators int整型二维数组 ops
* @param k int整型 the k
* @return int整型一维数组
*/
public int[] LFU (int[][] operators, int k) {
if (k == 0) {
return new int[0];
}
capacity = k;
List<Integer> retList = new ArrayList<>();
for (int[] operator : operators) {
if (operator[0] == 1) {
set(operator[1], operator[2]);
} else {
retList.add(get(operator[1]));
}
}
int[] res = new int[retList.size()];
for (int i = 0; i < retList.size(); i++) {
res[i] = retList.get(i);
}
return res;
}
private static class Node {
private final int key;
private Node left, right, up, down;
public Node(int key) {
this.key = key;
}
}
private static class KeyValOpTime {
private int key;
private int val;
private int opTime;
public KeyValOpTime(int key, int val, int opTime) {
this.key = key;
this.val = val;
this.opTime = opTime;
}
}
private static final Map<Integer, KeyValOpTime> keyMap = new HashMap<>();
private static final Map<Integer, Node> opMap = new HashMap<>();
private static final Map<Integer, Node> keyNodeMap = new HashMap<>();
private int capacity;
private Node opRoot;
private int sz;
private void deleteLowerestQuery() {
if (opRoot.up == opRoot) {
while (opRoot.up == opRoot) {
opRoot = opRoot.right;
}
}
Node opNode = opRoot;
Node tmp = opNode.up;
keyMap.remove(tmp.key);
keyNodeMap.remove(tmp.key);
Node node = opNode.up.up;
opNode.up = node;
node.down = opNode;
if (opNode.up == opNode) {
node = opNode.right;
opNode.right = null;
if (node != null) {
node.left = null;
}
opRoot = node;
}
sz--;
}
private void set(int key, int value) {
int opTime;
if (!keyMap.containsKey(key)) {
if (sz == capacity) {
deleteLowerestQuery();
}
opTime = 1;
keyMap.put(key, new KeyValOpTime(key, value, opTime));
if (opRoot == null) {
opRoot = new Node(opTime);
Node node = new Node(key);
opRoot.down = node;
node.up = opRoot;
opRoot.up = node;
node.down = opRoot;
opMap.put(opTime, opRoot);
keyNodeMap.put(key, node);
sz++;
} else if (!opMap.containsKey(opTime)) {
Node opNode = new Node(opTime);
Node node = new Node(key);
opNode.down = node;
node.up = opNode;
opNode.up = node;
node.down = opNode;
opNode.right = opRoot;
opRoot.left = opNode;
opMap.put(opTime, opNode);
keyNodeMap.put(key, node);
opRoot = opRoot.left;
sz++;
} else {
Node opNode = opMap.get(opTime);
Node node = new Node(key);
Node down = opNode.down;
node.down = down;
down.up = node;
node.up = opNode;
opNode.down = node;
keyNodeMap.put(key, node);
sz++;
}
} else {
KeyValOpTime keyValOpTime = keyMap.get(key);
opTime = keyValOpTime.opTime;
keyValOpTime.val = value;
keyValOpTime.opTime = opTime + 1;
keyMap.put(key, keyValOpTime);
dealWithMap(key, opTime);
}
}
private void dealWithMap(int key, int opTime) {
Node opNode = opMap.get(opTime);
Node node = keyNodeMap.get(key);
Node tmp = node.down;
node.up.down = tmp;
tmp.up = node.up;
if (opMap.get(opTime + 1) == null) {
tmp = new Node(opTime + 1);
tmp.down = node;
node.up = tmp;
tmp.up = node;
node.down = tmp;
Node right = opNode.right;
tmp.right = right;
if (right != null) {
right.left = tmp;
}
opNode.right = tmp;
tmp.left = opNode;
opMap.put(opTime + 1, tmp);
} else {
Node right = opMap.get(opTime + 1);
tmp = right.down;
node.down = tmp;
tmp.up = node;
right.down = node;
node.up = right;
}
if (opNode.down == opNode) {
Node left = opNode.left;
Node right = opNode.right;
right.left = left;
if (left != null) {
left.right = right;
}
opMap.remove(opTime);
}
}
private int get(int key) {
if (!keyMap.containsKey(key)) {
return -1;
}
KeyValOpTime keyValOpTime = keyMap.get(key);
int value = keyValOpTime.val;
int opTime = keyValOpTime.opTime;
keyValOpTime.opTime = opTime + 1;
keyMap.put(key, keyValOpTime);
dealWithMap(key, opTime);
return value;
}
}

小天才公司福利 1199人发布

查看3道真题和解析