题解 | #LFU缓存结构设计#
LFU缓存结构设计
http://www.nowcoder.com/practice/93aacb4a887b46d897b00823f30bfea1
java版本
核心:双Hashmap, 一个用作set,get操作,一个用作队列。
用作队列的HashMap 键为操作的次数,值为一个双链表链接所有具有相同操作的节点。
注意有插入和删除操作时应先判断 键 是否存在,删除最不常使用节点时应判断链表是否为空,为空应删除。
import java.util.*;
public class Solution {
/**
* lfu design
* @param operators int整型二维数组 ops
* @param k int整型 the k
* @return int整型一维数组
*/
class Node{
private int key, value, cnt;
private Node pre, next;
public Node(int key, int value){
this.key = key;
this.value = value;
this.cnt = 1;
this.pre = this.next = null;
}
}
class Que{
private Node head;
private Node tail;
public Que(Node head, Node tail){
this.head = head;
this.tail = tail;
this.head.next = this.tail;
this.tail.pre = this.head;
}
}
class Lfu{
private HashMap<Integer, Node> hashmap;
private HashMap<Integer, Que> que;
int size;
int least;
public Lfu(int size){
this.hashmap = new HashMap<>();
this.que = new HashMap<>();
this.size = size;
this.least = 1;
}
public void refresh(Node node){
if(this.que.containsKey(node.cnt)){
Que q1 = this.que.get(node.cnt);
node.next = q1.head.next;
node.pre = q1.head;
q1.head.next.pre = node;
q1.head.next = node;
}else{
Que q2 = new Que(new Node(-1, -1), new Node(-1, -1));
node.next = q2.head.next;
node.pre = q2.head;
node.next.pre = node;
q2.head.next = node;
this.que.put(node.cnt, q2);
}
}
public void set(int key, int value){
if(get(key) != -1){
Node node = this.hashmap.get(key);
node.value = value;
node.cnt += 1;
this.hashmap.put(key, node);
}else{
if(this.size == 0){
Que q = this.que.get(this.least);
this.hashmap.remove(q.tail.pre.key);
q.tail.pre.pre.next = q.tail;
q.tail.pre = q.tail.pre.pre;
if(q.head.next == q.tail){
this.que.remove(this.least);
while(!this.que.containsKey(this.least)) this.least++;
}
}else{
this.size --;
}
Node node = new Node(key, value);
this.hashmap.put(key, node);
this.least = 1;
refresh(node);
}
}
public int get(int key){
if(hashmap.containsKey(key)){
Node node = this.hashmap.get(key);
node.cnt ++;
node.pre.next = node.next;
node.next.pre = node.pre;
refresh(node);
return node.value;
}
return -1;
}
}
public int[] LFU (int[][] operators, int k) {
// write code here
ArrayList<Integer> arraylist = new ArrayList<>();
int[] res;
Lfu lfu = new Lfu(k);
for(int i = 0; i < operators.length; i++){
if(operators[i][0] == 1){
lfu.set(operators[i][1], operators[i][2]);
}else{
arraylist.add(lfu.get(operators[i][1]));
}
}
res = new int[arraylist.size()];
for(int i = 0; i < arraylist.size(); i++) res[i] = arraylist.get(i);
return res;
}
}

