为最近最少使用(LRU)缓存策略设计一个数据结构,它应该支持以下操作:获取数据(get)和写入数据(set)。
获取数据get(key):如果缓存中存在key,则获取其数据值(通常是正数),否则返回-1。
写入数据set(key, value):如果key还没有在缓存中,则写入其数据值。当缓存达到上限,它应该在写入新数据之前删除最近最少使用的数据用来腾出空闲位置。
解题思路:第一次做这个题没有思路,参考了九章算法的思路。
主要是用一个双向链表来存储节点,节点中包含键值对,map中存储key和节点,通过在map中查找key来定位node,所有最近被访问的数据被放在链表尾部,因此get方法中需要在查找到value之后将节点取出放到尾部,set中类似的考虑。
一刷没有ac
二刷没有ac
public class Solution {
public class Node{
Node pre;
Node next;
int key;
int val;
public Node(int key, int val){
this.key = key;
this.val = val;
this.pre = null;
this.next = null;
}
}
public int capacity;
public HashMap<Integer, Node> map = new HashMap<Integer, Node>();
public Node head = new Node(-1,-1);
public Node tail = new Node(-1,-1);
// @param capacity, an integer
public Solution(int capacity) {
this.capacity = capacity;
head.next = tail;
tail.pre = head;
}
// @return an integer
public int get(int key) {
if(!map.containsKey(key)){
return -1;
}
Node current = map.get(key);
current.next.pre = current.pre;
current.pre.next = current.next;
move_to_tail(current);
return map.get(key).val;
}
// @param key, an integer
// @param value, an integer
// @return nothing
public void set(int key, int value) {
if(get(key) != -1){
Node node = map.get(key);
node.prev.next = node.next;
node.next.prev = node.prev;
move_to_tail(node);
map.get(key).val = value;
return;
}
if(map.size() == capacity){
map.remove(head.next.key);
head.next = head.next.next;
head.next.pre = head;
}
Node insert = new Node(key,value);
move_to_tail(insert);
map.put(key,insert);
}
public void move_to_tail(Node node){
node.pre = tail.pre;
tail.pre.next = node;
node.next = tail;
tail.pre = node;
}
}