package NC;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* NC93 设计LRU缓存结构
*
* 设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设大小为 k,并有如下两个功能
* 1. set(key, value):将记录(key, value)插入该结构
* 2. get(key):返回key对应的value值
*
* 提示:
* 1.某个key的set或get操作一旦发生,认为这个key的记录成了最常使用的,然后都会刷新缓存。
* 2.当缓存的大小超过k时,移除最不经常使用的记录。
* 3.输入一个二维数组与k,二维数组每一维有2个或者3个数字,第1个数字为opt,第2,3个数字为key,value
* 若opt=1,接下来两个整数key, value,表示set(key, value)
* 若opt=2,接下来一个整数key,表示get(key),若key未出现过或已被移除,则返回-1
* 对于每个opt=2,输出一个答案
* 4.为了方便区分缓存里key与value,下面说明的缓存里key用""号包裹
*
* @author Tang
* @date 2021/9/24
*/
public class LRU {
public int[] LRU (int[][] operators, int k) {
// write code here
List<Object> result = new ArrayList<>();
LinkedMap linkedMap = new LinkedMap(k);
for(int i = 0; i < operators.length; i++) {
int[] operator = operators[i];
if(operator[0] == 2) {
Object o = linkedMap.get(operator[1]);
result.add(o == null ? -1 : o);
}else {
linkedMap.put(operator[1], operator[2]);
}
}
int[] results = new int[result.size()];
for(int i = 0; i < result.size(); i++) {
results[i] = (int) result.get(i);
}
return results;
}
public static void main(String[] args) {
LinkedMap linkedMap = new LinkedMap(3);
linkedMap.put(3,3);
linkedMap.put(1,1);
linkedMap.put(2,2);
linkedMap.put(3,4);
linkedMap.put(5,5);
linkedMap.put(6,6);
linkedMap.put(7,7);
System.out.println(linkedMap.size());
System.out.println(linkedMap.get(7));
int[][] num = {{1,1,1},{1,2,2},{1,3,2},{2,1},{1,4,4},{2,2}};
new LRU().LRU(num, 3);
}
}
class LinkedMap {
/**
* 首元素 不用做存储数据
*/
Entry first = new Entry(null,null);
Entry last;
int size;
int max;
public LinkedMap(int max) {
this.max = max;
}
public int size() {
return size;
}
private Entry search(Object key) {
//从头遍历找到元素
Entry head = first;
Entry result = null;
while(head != null) {
if(key.equals(head.getKey())) {
result = head;
break;
}
head = head.getNext();
}
return result;
}
public void put(Object key, Object value){
Entry entry = new Entry(key, value);
Entry head = first.getNext();
while (head != null) {
head = head.getNext();
}
if(first.getNext() == null) {
first.setNext(entry);
last = entry;
last.setPre(first);
size++;
return;
}
//头插法加入新元素
entry.setNext(first.getNext());
entry.setPre(first);
first.getNext().setPre(entry);
first.setNext(entry);
size++;
//当size达到最大,删除last元素
if(size > max) {
last = last.getPre();
last.setNext(null);
size--;
}
}
public Object get(Object key) {
Entry search = search(key);
if(search == null) {
return null;
}
//找到后将元素置于头部
Entry pre = search.getPre();
Entry next = search.getNext();
pre.setNext(next);
if(next != null) {
next.setPre(pre);
}
search.setNext(first.getNext());
if(first.getNext() != null) {
first.getNext().setPre(search);
}
first.setNext(search);
return search.getValue();
}
}
class Entry {
private Object key;
private Object value;
private Entry pre;
private Entry next;
public Entry(Object key, Object value) {
this.key = key;
this.value = value;
}
public Entry getPre() {
return pre;
}
public void setPre(Entry pre) {
this.pre = pre;
}
public Entry getNext() {
return next;
}
public void setNext(Entry next) {
this.next = next;
}
public Object getKey() {
return key;
}
public void setKey(Object key) {
this.key = key;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}