題目描述
設計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);
}
}