提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
此文章用于自己学习记录。
面试官:对LRU算法了解过吗?实现LRU,要求get、和put操作都是O(1)。
实现O(1)操作可以用Map和双向链表两种集合可以轻松实现LRU。
直接上代码
/**
* 手写LRU,使得get和put都是O(0)
*/
public class LruDemo {
//默认存储最大值
private int MAXSIZE = 10;
//当前存储数据个数
private int size = 0;
private Map<String, Link> map = new HashMap<>();
//头部,不存数据,用来定位
private Link head = new Link();
//尾部
private Link wei = new Link();
public LruDemo(int max) {
this.MAXSIZE = max;
//实例化必须将头尾相连
head.next = wei;
wei.prv = head;
}
public String get(String key) {
if (map.containsKey(key)) {
Link link = map.get(key);
//使目标link的上一个link 和 下一个link 相连
link.prv.next = link.next;
link.next.prv = link.prv;
//将link移动到第一位
link.next = head.next;
head.next.prv = link;
link.prv = head;
head.next = link;
return map.get(key).value;
}
return null;
}
public void put(String key, String value) {
if (map.containsKey(key)) {
Link linkIndex = map.get(key);
linkIndex.value = value;
map.put(key, linkIndex);
//TODO 移动到链表头部
linkIndex.prv.next = linkIndex.next;
linkIndex.next.prv = linkIndex.prv;
head.next.prv = linkIndex;
linkIndex.next = head.next;
head.next = linkIndex;
linkIndex.prv = head;
return;
}
if (size >= MAXSIZE) {
//TODO 删除尾节点
Link link1 = wei.prv.prv;
Link link2 = wei.prv;
link1.next = wei;
link2.prv = null;
link2.next = null;
wei.prv = link1;
size--;
}
Link link = new Link(key, value);
map.put(key, link);
head.next.prv = link;
link.next = head.next;
link.prv = head;
head.next = link;
size++;
}
/**
* 用于测试:正序打印
*/
public void printLruDemoASC() {
Link index = head.next;
int i = 1;
while (index != null && index != wei) {
System.out.println("第" + i + "个: key = " + index.key + " value = " + index.value);
index = index.next;
i++;
}
}
/**
* 用于测试:倒打印
*/
public void printLruDemoDESC() {
Link index = wei.prv;
int i = size;
while (index != null && index != head) {
System.out.println("第" + i + "个: key = " + index.key + " value = " + index.value);
index = index.prv;
i--;
}
}
public int size() {
return this.size;
}
class Link {
String value;
String key;
Link prv;
Link next;
public Link(String key, String value) {
this.key = key;
this.value = value;
}
public Link() {
}
}
}