class LRUCache {
//采用链表+hashmap的方式来实现
DobbleLinkedList linkedList;
HashMap<Integer, Node<Integer>> keyNodeMap;
//反向存key value 为了后面删除元素的时候方便通过node找到key,以便于keyNodeMap中删除key
HashMap<Node<Integer>, Integer> nodeKeyMap;
int capacity;
public LRUCache(int capacity) {
if(capacity <= 0)
throw new RuntimeException(" capacity should be more than zero !");
this.capacity = capacity;
this.linkedList = new DobbleLinkedList();
this.keyNodeMap = new HashMap<>();
this.nodeKeyMap = new HashMap<>();
}
public int get(int key) {
if(this.keyNodeMap.containsKey(key)){
Node<Integer> node = this.keyNodeMap.get(key);
linkedList.moveNodeToTail(node);
return node.v;
}
return -1;
}
public void put(int key, int value) {
Node<Integer> node;
if(this.keyNodeMap.containsKey(key)){
node = this.keyNodeMap.get(key);
node.v = value;
} else {
node = new Node(value);
this.keyNodeMap.put(key,node);
this.nodeKeyMap.put(node,key);
this.linkedList.addToTail(node);
}
this.linkedList.moveNodeToTail(node);
if(this.capacity + 1 == this.keyNodeMap.size()){
node = this.linkedList.removeFromHead();
Integer k = this.nodeKeyMap.get(node);
this.nodeKeyMap.remove(node);
this.keyNodeMap.remove(k);
}
}
}
class Node<V>{
Node pre;
Node next;
V v;
Node(){}
Node(V v){
this.v = v;
}
}
class DobbleLinkedList{
Node head;
Node tail;
public Node addToTail(Node newNode){
if(this.head == null){
this.head = newNode;
this.tail = newNode;
} else{
this.tail.next = newNode;
newNode.pre =this.tail;
this.tail = newNode;
}
return this.head;
}
public Node removeFromHead(){
if(this.head == null)
return null;
Node oldHead = this.head;
Node newHead = this.head.next;
if(newHead == null){
this.head = null;
} else {
newHead.pre = null;
this.head.next = null;
this.head = newHead;
}
return oldHead;
}
//将使用过的元素移动到双向链表的最末尾,因为删除元素的时候会删除头节点
public void moveNodeToTail(Node node){
if(node == null || node == this.tail) return;
if(node == this.head){
this.head = this.head.next;
this.head.pre = null;
node.next = null;
} else {
Node pre = node.pre;
pre.next = node.next;
node.next.pre = pre;
node.next = null;
}
this.tail.next = node;
node.pre = this.tail;
this.tail = node;
}
}
手写LRU,以及自己实现一个简易的双向链表
最新推荐文章于 2022-08-31 13:47:05 发布