解法
样例 [[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]],3
第一个数字 1 代表 set方法, 2 代表 get方法
第二个第三个 代表 key value
最后一个数字是 k 代表长度 只能容纳多少个key value。
输入的是 每次get的值。 如果找不到就是-1;
本质上还是运用双向链表实现 LRU ,HashMap 只是为了更快的查询到key
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9cNYCfqa-1599787344044)(https://uploadfiles.nowcoder.com/images/20200904/1733825_1599181955298_89A57547889C70BBE4CC12F483928DD8 “图片标题”)]
当我们遇到第一个set方法的时候 就需要插入到head 和tail 之间,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6GvJiYPq-1599787344048)(https://uploadfiles.nowcoder.com/images/20200904/1733825_1599182022316_928A700DBE48FD03AC7827C18C0B6C5D “图片标题”)]
每次插入都放在head的后面 因为是最近最少使用嘛,你使用了就放在头结点后面就可以了。最后是这样的链表。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UTAEvHOL-1599787344050)(https://uploadfiles.nowcoder.com/images/20200904/1733825_1599182188374_8A7778ECCD17B96575464054AB942A94 “图片标题”)]
当我们遇到get的时候,就把需要被get的结点 给移除,然后放在头结点。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A3jY7kYO-1599787344056)(https://uploadfiles.nowcoder.com/images/20200904/1733825_1599182271135_0D4C754A0774FA442D2CF32297769541 “图片标题”)]
遇到需要自动移除结点的时候,就把这个结点移除就OK了,然后新放入的结点还是放在head的后面。
代码
import java.util.*;
public class Solution {
static class Node{
int key , value;
Node prev,next;
public Node(int key , int value){
this.key = key;
this.value = value;
}
}
private Map<Integer,Node> map = new HashMap<>();
private Node head = new Node(-1,-1);
private Node tail = new Node(-1,-1);
private int k;
public int[] LRU (int[][] operators, int k) {
// write code here
this.k = k;
head.next = tail;
tail.prev = head;
int len =(int) Arrays.stream(operators).filter(x->x[0] == 2).count();
int[] ans = new int[len];
int cnt = 0;
for(int i=0;i < operators.length ;i++){
if(operators[i][0] == 1){
set(operators[i][1],operators[i][2]);
}else{
ans[cnt++] = get(operators[i][1]);
}
}
return ans;
}
public void set(int key,int value){
if(get(key) > -1){
map.get(key).value = value;
}else{
if(map.size() == k ){
int rk = tail.prev.key;
tail.prev.prev.next = tail;
tail.prev = tail.prev.prev;
map.remove(rk);
}
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.prev.next = node.next;
node.next.prev = node.prev;
removeToHead(node);
return node.value;
}
return -1;
}
public void removeToHead(Node node){
node.next = head.next;
head.next.prev = node;
head.next = node;
node.prev = head;
}
}