LRU算法应该对所有计算机\软工的同学都不陌生了。
那么要如何实现LRU算法呢?
LRU算法需要设计一个数据结构,这个数据结构有两个操作,一个是get(key):获取key对应的value,如果key不存在则返回-1
put(key, value): 存入键值对
以上两个操作的复杂度都应该为O(1)
分析上述操作,总结这个数据结构的必要条件为:查找快、插入块、删除快、有序
哈希表查找快,但无序
链表有顺序,但查找慢,结合形成哈希链表。
可以写下以下代码
代码
class Node{
Node prev, next;
int key, value;
public Node(int key, int value){
this.key = key;
this.value = value;
this.prev = null;
this.next = null;
}
}
class LRUCache {
int capacity;
Node head, tail;
HashMap<Integer, Node> map;
public LRUCache(int capacity) {
this.capacity = capacity;
head = new Node(-1, -1);
tail = new Node(-1, -1);
head.next = tail;
tail.prev = head;
map = new HashMap<>();
}
private void addFirst(Node x){
Node nex = head.next;
head.next = x;
x.prev = head;
x.next = nex;
nex.prev = x;
}
private void remove(Node x){
x.prev.next = x.next;
x.next.prev = x.prev;
}
private Node removeLast(){
Node lastNode = tail.prev;
lastNode.prev.next = tail;
tail.prev = lastNode.prev;
return lastNode;
}
public int get(int key) {
if(!map.containsKey(key))
return -1;
int value = map.get(key).value;
put(key, value);
return value;
}
public void put(int key, int value) {
Node x = new Node(key, value);
if(map.containsKey(key)){
remove(map.get(key));
addFirst(x);
map.put(key, x);
}else{
if(capacity == map.size()){
Node lastNode = removeLast();
map.remove(lastNode.key);
}
addFirst(x);
map.put(key, x);
}
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/