一开始也不会写,通过看了一下大佬们的代码,写了出来,还有的大佬是直接通过一个集合,一个哈希表写出来,感觉都好牛逼但是我觉得整体的思路都是一样的,在这我是进行了一个总结。
利用一个Map来判断存入结点数是否越界,如果越界就要进行缺页处理,换出最近最久未使用的页。Set函数如果在Map存在就直接进行更新,get函数用于更新,如果包含,就删除该节点放在双向链表的队头;否则返回-1;再用一个函数moveToHead将结点移动到队头。
import java.util.;
public class Solution {
/*

* lru design
* @param operators int整型二维数组 the ops
* @param k int整型 the k
* @return int整型一维数组
*/
private Map<Integer,Node> map=new HashMap<>();//缓存区
private Node head=new Node(-1,-1);//头结点
private Node tail=new Node(-1,-1);//尾结点
private int k=0;//缓存区大小
public int[] LRU (int[][] operators, int k) {
// write code here
this.k=k;
//构建双向链表
head.next=tail;
tail.prev=tail;
//获取数组中进行get操作的数目
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){
this.set(operators[i][1],operators[i][2]);
}else{
res[j++]=this.get(operators[i][1]);
}
}
return res;
}
private void set(int key,int value){
if(this.get(key)>-1){//缓存中存在,更新数值
map.get(key).value=value;
}else{
if(map.size()==k){//缓存区满,进行缺页处理,删除末尾结点
int last=tail.prev.key;
tail.prev.prev.next=tail;
tail.prev=tail.prev.prev;
map.remove(last);
}
//将新结点移动到头
Node node=new Node(key,value);
map.put(key,node);
this.moveToHead(node);
}
}
private int get(int key){
if(map.containsKey(key)){//包含结点,进行更新,删除该节点,移动到头
Node node=map.get(key);
node.prev.next=node.next;
node.next.prev=node.prev;
moveToHead(node);
return node.value;
}
return -1;
}
//将结点移动到头
private void moveToHead(Node node){
node.next=head.next;
head.next.prev=node;
node.prev=head;
head.next=node;
}
//结点类
static class Node{
int key,value;
Node prev,next;
public Node(int key,int value){
this.key=key;
this.value=value;
}
}
}