题目描述
设计LRU缓存结构,该结构在构造时确定大小,假设大小为K,并有如下两个功能
set(key, value):将记录(key, value)插入该结构
get(key):返回key对应的value值
[要求]
set和get方法的时间复杂度为O(1)
某个key的set或get操作一旦发生,认为这个key的记录成了最常使用的。
当缓存的大小超过K时,移除最不经常使用的记录,即set或get最久远的。
输入描述:
第一行两个个整数N, K,表示操作数量以及缓存结构大小
接下来N行,第一行一个整数opt表示操作类型。
若opt=1,接下来两个整数x, y,表示set(x, y)
若opt=2,接下来一个整数x,表示get(x),若x未出现过或已被移除,则返回-1
输出描述:
对于每个操作2,输出一个答案
示例1
输入
6 3
1 1 1
1 2 2
1 3 2
2 1
1 4 4
2 2
输出
1
-1
解法一:双端链表+两个map
import java.io.*;
import java.util.*;
public class Main{
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws Exception{
String[] ss = br.readLine().trim().split(" ");
int nums = Integer.parseInt(ss[0]);
int capcity = Integer.parseInt(ss[1]);
fun(nums,capcity);
}
public static void fun(int nums,int capcity) throws IOException {
MyCache<Integer,Integer> mycache = new MyCache(capcity);
for(int i=0;i<nums;i++) {
String[] info = br.readLine().trim().split(" ");
if("1".equals(info[0])) {
int key = Integer.parseInt(info[1]);
int val = Integer.parseInt(info[2]);
mycache.set(key, val);
}else {
int key = Integer.parseInt(info[1]);
Integer res = mycache.get(key);
System.out.println(res==null?-1:res);
}
}
}
}
class Node<V>{
V val;
Node<V> last;
Node<V> next;
public Node(V val){
this.val = val;
}
}
class DoubleLink<V>{
Node<V> head;
Node<V> tail;
public DoubleLink(){
head = null;
tail = null;
}
public void addNode(Node<V> node){
if(node==null) return;
if(tail==null){
head = node;
tail = node;
}else{
tail.next = node;
node.last = tail;
tail = node;
}
}
public void moveNodeToTail(Node<V> node){
if(node==null) return;
if(node==tail) return;
if(node==head){
head = head.next;
head.last = null;
}else {
node.last.next = node.next;
node.next.last = node.last;
}
tail.next = node;
node.last = tail;
tail = node;
node.next = null;
}
public Node<V> removeHead(){
if(head==null) return null;
Node<V> res = head;
if(tail==head){
head = null;
tail = null;
}else{
head = head.next;
head.last = null;
res.next = null;
}
return res;
}
}
class MyCache<K,V>{
HashMap<K,Node<V>> keyNode;
HashMap<Node<V>,K> nodeKey;
int capacity;
DoubleLink<V> link;
public MyCache(int cap){
keyNode = new HashMap<>();
nodeKey = new HashMap<>();
this.capacity = cap;
link = new DoubleLink();
}
public V get(K key){
if(keyNode.containsKey(key)){
Node<V> res = keyNode.get(key);
link.moveNodeToTail(res);
return res.val;
}
return null;
}
public void set(K key,V val){
if(keyNode.containsKey(key)){
Node<V> node = keyNode.get(key);
node.val = val;
link.moveNodeToTail(node);
}else{
Node<V> node = new Node<V>(val);
keyNode.put(key,node);
nodeKey.put(node,key);
link.addNode(node);
if(keyNode.size()==capacity+1){
removeMostUnused();
}
}
}
public void removeMostUnused(){
Node<V> head = link.removeHead();
K key = nodeKey.get(head);
nodeKey.remove(head);
keyNode.remove(key);
}
}