问题描述
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
解题思路
LRU算法是最近最少使用算法,举例:
在cache中存储了一系列的键值对:“001”—“用户001”;“002”—“用户002”;“003”—“用户003”;“004”—“用户004”。对用户按键值对存储,在按key进行查询时,经常查询的可以直接获取,不经常访问的编号,不存储在其中。
用hashmap+双向链表来实现,对于最新访问的键值对,存储在双向链表尾部;而头部是不经常访问的键值对;对于新出现的键值对,如果链表满了,则删除头部node,在尾部插入node;
问题中两个方法:
- get(key)方法:
根据key值,返回value值,如果不存在,则返回-1;
get(key):
hashmap.get(key) --检查是否存在
存在key值:
removenode(node) --调用removenode方法
addnode(node)
return node.value
不存在key值:
return -1; - put(key,value)方法:
将key-value put中
put(key,value):
hashmap.get(key) ----检查是更新还是放入新值
放入新值:
hashmap.size ----检查是否放满
oldkey=removenode(node) ----满了
hashmap.remove(oldkey)
addnode(node)
hashmap.put(key,node)
更新值: ----将新访问node移到末端
node.value=value
removenode(node)
addnode(node)Code
import java.util.HashMap;
/**
*
* @author 22072
* Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.
* get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
* put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity,
* it should invalidate the least recently used item before inserting a new item.
* Follow up: Could you do both operations in O(1) time complexity?
*
*/
public class Leetcode146 {
private int capacity;
private Node1 end;
private Node1 head;
private HashMap<Integer, Node1> hashMap;
//这里capacity代表cache大小
public Leetcode146(int capacity){
this.capacity=capacity;
hashMap=new HashMap<Integer,Node1>();
}
//get方法,先检查LRUCache中是否存在,如果存在,返回value值,并且将key-value挪到链表尾部;不存在,返回-1
public int get(int key){
Node1 node1=hashMap.get(key);
if(node1==null){
return -1;
}else{
refreshNode(node1);
return node1.value;
}
}
//set方法,先检查key是否存在,如果存在替换value值,然后不存在时,检查cache是否capacity,如果满,删除一个,然后插入,从尾部插入;未满,直接插入尾部
public void put(int key, int value){
Node1 node1=hashMap.get(key);
if(node1==null){
if(hashMap.size()>=capacity){
int oldkey=removeNode(head);
hashMap.remove(oldkey);
}
node1=new Node1(key, value);
addNode(node1);
hashMap.put(key, node1);
}else{
node1.value=value;
refreshNode(node1);
}
}
private void refreshNode(Node1 node1) {
if(node1==end){
return;
}
removeNode(node1);
addNode(node1);
}
private void addNode(Node1 node1) {
if(end!=null){
end.next=node1;
node1.pre=end;
node1.next=null;
}
end=node1;
if (head==null) {
head=node1;
}
}
private int removeNode(Node1 node1) {
if(head==node1){
head=node1.next;
}else if(end==node1){
end=node1.pre;
}else{
node1.pre.next=node1.next;
node1.next.pre=node1.pre;
}
return node1.key;
}
}
class Node1{
Node1(int key,int value){
this.key=key;
this.value=value;
}
public int key;
public int value;
public Node1 pre;
public Node1 next;
}
/**
* 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);
*/
新学习的微信文章https://mp.weixin.qq.com/s/B5xiVeW22ZumbI9KfrYJSg
谢谢