import java.util.*;
//双向链表
class Node {
int key ;//键
int val ;//值
Node pre ;
Node nxt ;
Node(int key , int val) {
this.key = key ;
this.val = val ;
}
}
public class Solution {
HashMap<Integer , Node> map ;//存储数据+查询
int maxSize ;//最大容量
int size ;//当前容量
//双向链表保存数据的访问时间情况,链头为最近使用,链尾为最久未使用
Node head_pre ;//最近使用的结点 的上一个结点(辅助结点,免去考虑在链头、链尾操作的特殊情况)
Node tail_nxt ;//最久未使用的结点的 上一个结点(辅助结点)
public Solution(int capacity) {
map = new HashMap<>() ;
this.size = 0 ;
this.maxSize = capacity ;
head_pre = new Node(-1,-1) ;
tail_nxt = new Node(-1,-1) ;
head_pre.nxt = tail_nxt ;//构建双向链表
tail_nxt.pre = head_pre ;
}
public int get(int key) {
if(!map.containsKey(key)) {
return -1 ;
} else {
Node find = map.get(key) ;
moveToHead(find) ;//将访问的节点移动到最近使用的位置(即,链表头)
return find.val ;
}
}
public void set(int key, int value) {
if(map.containsKey(key)) {
Node find = map.get(key) ;
find.val = value ;
moveToHead(find) ;
} else {
Node newNode = new Node(key , value) ;
if(this.size == this.maxSize) {
Node last = removeTail() ;//移除最久未使用的
map.remove(last.key) ;
map.put(key , newNode) ;
insertHead(newNode) ;
} else {
map.put(key , newNode) ;
insertHead(newNode) ;
this.size ++ ;
}
}
}
//将节点移动到最近使用的位置(即,链表头)
public void moveToHead(Node node) {
if(node.pre == head_pre) {
return ;
} else {
node.pre.nxt = node.nxt ;
node.nxt.pre = node.pre ;
node.nxt = null ;
node.pre = null ;
insertHead(node) ;
}
}
//在链表头插入
public void insertHead(Node node) {
node.nxt = head_pre.nxt ;
head_pre.nxt = node ;
node.nxt.pre = node ;
node.pre = head_pre ;
}
//移除最后一个结点(最久未使用的),然后返回这个结点
public Node removeTail() {
if(head_pre.nxt == tail_nxt) return null ;
Node target = tail_nxt.pre ;
target.pre.nxt = target.nxt ;
target.nxt.pre = target.pre ;
target.pre = null ;
target.nxt = null ;
return target ;
}
}
/**
* Your Solution object will be instantiated and called as such:
* Solution solution = new Solution(capacity);
* int output = solution.get(key);
* solution.set(key,value);
*/