import java.util.*;
public class Solution {
/**
* lfu design
* @param operators int整型二维数组 ops
* @param k int整型 the k
* @return int整型一维数组
*/
public int[] LFU (int[][] operators, int k) {
// write code here
if(operators == null || operators.length == 0){return new int[0];}
List res = new ArrayList<>(10);
MyLFU lfu = new MyLFU(k);
for(int[] oper : operators){
if(oper.length == 3){
lfu.set(oper[1], oper[2]);
}else{
res.add(lfu.get(oper[1]));
}
}
int len = res.size();
int[] arr = new int[len];
for(int i = 0; i
arr[i] = res.get(i);
}
return arr;
}
private class MyLFU{
private class Node{
public int key;
public int val;
public int count;
public Node next;
public Node prev;
public Node(int k, int v){
this.key = k;
this.val = v;
this.count = 0;
}
}
private class MyLinkedList{
private Map map = new HashMap<>(16);
private Node head = new Node(0, 0); // head.next为最后删除的元素
private Node tail = new Node(0, 0); // tail.prev为优先删除的元素
private int size = 0;
public MyLinkedList(){
this.head.next = this.tail;
this.tail.prev = this.head;
}
public int size(){return this.size;}
public Node pop(){
Node node = this.tail.prev;
if(node == this.head){return null;}
node.prev.next = this.tail;
this.tail.prev = node.prev;
map.remove(node.key);
--size;
return node;
}
public void add(Node node){
node.next = this.head.next;
node.next.prev = node;
this.head.next = node;
node.prev = this.head;
map.put(node.key, node);
++size;
}
public void removByKey(int key){
if(!this.map.containsKey(key)){return;}
Node node = map.get(key);
node.prev.next = node.next;
node.next.prev = node.prev;
map.remove(key);
--size;
}
}
private int size = 0;
private int minCount = 1;
private int capacity;
private Map nodes = new HashMap<>(16); // key->Node
private Map freqs = new HashMap<>(16); // count->MyLinkedList
public MyLFU(int k){
this.capacity = k;
}
public int get(int key){
if(this.nodes.containsKey(key)){
Node node = this.nodes.get(key);
this.move(node);
return node.val;
}
return -1;
}
public void set(int key, int val){
Node node;
if(!this.nodes.containsKey(key)){
node = new Node(key, val);
this.nodes.put(key, node);
++this.size;
}else{
node = this.nodes.get(key);
node.val = val;
}
this.move(node);
if(this.size > this.capacity){
MyLinkedList list = this.freqs.get(this.minCount);
Node poped = list.pop();
this.nodes.remove(poped.key);
if(list != null || list.size() == 0){
this.minCount = 0;
do{
list = this.freqs.getOrDefault(++this.minCount, null);
}while(list == null || list.size() == 0);
}
--this.size;
}
}
private void move(Node node){
MyLinkedList list = this.freqs.getOrDefault(node.count, null);
if(list != null){ list.removByKey(node.key); }
int newCount = ++node.count;
if(!this.freqs.containsKey(newCount)){
list = new MyLinkedList();
this.freqs.put(newCount, list);
}else{
list = this.freqs.get(newCount);
}
list.add(node);
}
}
}