题解 | #设计LRU缓存结构#
设计LRU缓存结构
https://www.nowcoder.com/practice/5dfded165916435d9defb053c63f1e84
import java.util.*;
/*
解题思路
主要使用map,和双端链表解决问题
map-> key,就是你传入的key
map->value 就是一个node节点
get(key) 表示你传入的key,查map,如果有值,调整链表node节点到头.返回node.val
set(key,val) 先判断当前key元素是否在Map中,如果已经存在,直接更新node.val,并且调整node节点到表头
如果不存在,先判断链表的大小,是否已经大于其容量,如果没有大于,直接存放,并调整链表,如果大于,删除最尾部node,把需要存放的元素,放到node链表的头部
*/
public class Solution {
private int capacity;
private Map<Integer, Node> map;
private Node head;
private Node tail;
private int used;
class Node {
int key;
int value;
Node prev;
Node next;
Node(int key, int value, Node prev, Node next) {
this.key = key;
this.value = value;
this.prev = prev;
this.next = next;
}
}
public Solution(int capacity) {
//该出的逻辑是初始化当前双端链表的大小
// write code here
this.capacity = capacity;
this.map = new HashMap<>();
//表示链表使用情况
this.used = 0;
}
public int get(int key) {
// write code here
if (!map.containsKey(key)) {
return -1;
}
makeRecently(key);
return map.get(key).value;
}
public void set(int key, int value) {
// 如果 key 已存在,直接修改值,再移到链表头部
if (map.containsKey(key)) {
map.get(key).value = value;
makeRecently(key);
return;
}
// 如果达到容量上限,就要移除尾部节点,注意 HashMap 要 remove!!!
if (used == capacity) {
map.remove(tail.key);
tail = tail.prev;
tail.next = null;
used--;
}
// 头节点为空,单独处理
if (head == null) {
head = new Node(key, value, null, null);
tail = head;
} else {
Node node = new Node(key, value, null, head);
head.prev = node;
head = node;
}
map.put(key, head);
used++;
}
// 把 key 对应的节点移到链表头部
private void makeRecently(int key) {
Node node = map.get(key);
if(node == head){
return;
}
if (node == tail) {
tail = tail.prev;
tail.next = null;
} else {
node.prev.next = node.next;
node.next.prev = node.prev;
}
node.prev = null;
node.next = head;
head.prev = node;
head = node;
}
}
/**
* Your Solution object will be instantiated and called as such:
* Solution solution = new Solution(capacity);
* int output = solution.get(key);
* solution.set(key,value);
*/
