题目:
题目的传送门在这里
思路:
太困了,先看注释吧,改天更新
import java.util.*;
public class Solution {
/**
* lru design
* @param operators int整型二维数组 the ops
* @param k int整型 the k
* @return int整型一维数组
*/
static class Node{
int key, value;
Node pre, next;
public Node(int key, int value){
this.key = key;
this.value = value;
}
}
private Map<Integer, Node> map = new HashMap<Integer, Node>();
private Node head = new Node(-1, -1);
private Node tail = new Node(-1, -1);
public int k;
public int[] LRU (int[][] operators, int k) {
// write code here
this.k = k;
head.next = tail;
tail.pre = head;
// 获取数组长度,这句代码强,给我看懵了
int len = (int)Arrays.stream(operators).filter(x -> x[0] == 2).count();
int[] res = new int[len];
for(int i = 0, j = 0; i < operators.length; i++) {
if(operators[i][0] == 1) {
set(operators[i][1], operators[i][2]);
} else {
res[j++] = get(operators[i][1]);
}
}
return res;
}
public void set(int key, int value){
if(get(key) > -1){ //如果里面有key的话,需要更新一下key的value值
map.get(key).value = value;
}else{
if(map.size() == k){ // 如果存储满了,那么需要先删除尾部元素,再新建节点并头插
// 删除之前先存储
int rk = tail.pre.key;
// 删除尾部元素( node6->node7->tail, 删除node7)
tail.pre.pre.next = tail;
tail.pre = tail.pre.pre;
// 删掉map
map.remove(rk);
}
// 注意:这个新建节点并头插这个步骤是必须做的,缓存满不满都需要做。
// 新建节点,放入map,并头插。
Node node = new Node(key, value);
map.put(key, node);
removeToHead(node);
}
}
public int get(int key){
if(map.containsKey(key)){
Node node = map.get(key);
// 先断掉
node.next.pre = node.pre; //1
node.pre.next = node.next; //2
// 再头插
removeToHead(node);
return node.value;
}else{
return -1;
}
}
// 双线链表的头插法
public void removeToHead(Node node){
// 头插
head.next.pre = node; //2
node.next = head.next;//1
head.next = node; //3
node.pre = head; //4
}
}