package com.heu.wsq.niuke.top200;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LRU {
public int[] LRU (int[][] operators, int k) {
List<Integer> list = new ArrayList<>();
LRUCache lruCache = new LRUCache(k);
for(int[] op: operators){
if(op[0] == 1){
lruCache.set(op[1], op[2]);
}else if(op[0] == 2){
list.add(lruCache.get(op[1]));
}
}
int[] ans = new int[list.size()];
for(int i = 0; i < list.size(); i++){
ans[i] = list.get(i);
}
return ans;
}
}
class LRUCache{
class LinkedNode{
private int key;
private int value;
private LinkedNode prev;
private LinkedNode next;
public LinkedNode(){}
public LinkedNode(int key, int value){
this.key = key;
this.value = value;
}
}
private LinkedNode head;
private LinkedNode tail;
private Map<Integer, LinkedNode> cache;
private int capacity;
public LRUCache(int k){
this.cache = new HashMap<>();
this.capacity = k;
this.head = new LinkedNode();
this.tail = new LinkedNode();
this.head.next = this.tail;
this.tail.prev = this.head;
}
public void set(int k, int v){
LinkedNode node = this.cache.get(k);
if(node == null){
node = new LinkedNode(k, v);
this.cache.put(k, node);
addToHead(node);
if(this.cache.size() > this.capacity){
LinkedNode tailNode = rmTailNode();
this.cache.remove(tailNode.key);
}
}else{
node.value = v;
rmNodeToHead(node);
}
}
public int get(int k){
LinkedNode node = this.cache.get(k);
if(node != null){
rmNodeToHead(node);
}
return node == null ? -1 :node.value;
}
private void rmNodeToHead(LinkedNode node){
rmNode(node);
addToHead(node);
}
private void rmNode(LinkedNode node){
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void addToHead(LinkedNode node){
node.next = this.head.next;
this.head.next = node;
node.prev = this.head;
node.next.prev = node;
}
private LinkedNode rmTailNode(){
LinkedNode node = this.tail.prev;
rmNode(node);
return node;
}
}