当年oracle面试时,ravi就反复问我们这道题,当时竟然不知这是一道可以准备的高频题,当然最重要的是当时只是限于用queue和map去做了,没有想到用双向循环列表。虽然最后过了,但心中一直抱憾。今天我们终于要面对这道题,觉得这道题如果想到了用双向循环列表和map就没有技术难度了,剩下的只是对lru的理解,和链表操作的基本功。于是在我们的code中,这两点都犯了错误,尤其是lru的理解,第4个错误是我们看了答案才找到的。。。
常温故知新,想想错在哪里了
public class Solution {
private class Node {
Node prev;
Node next;
int key;
int value;
public Node(int key, int value) {
this.key = key;
this.value = value;
}
}
private Node head = new Node(-1, -1);
private Node tail = new Node(-1, -1);
private Map<Integer, Node> map = new HashMap<>();
private int capacity = 0;
// @param capacity, an integer
public Solution(int capacity) {
// write your code here
head.prev = tail;
tail.next = head;
1
head.next = tail;
tail.prev = head;
1
this.capacity = capacity;
}
// @return an integer
public int get(int key) {
// write your code here
if (!map.containsKey(key)) {
return -1;
}
Node temp = map.get(key);
temp.next.prev = temp.prev;
temp.prev.next = temp.next;
moveAfterHead(temp);
return temp.value;
}
// @param key, an integer
// @param value, an integer
// @return nothing
public void set(int key, int value) {
// write your code here
//4 if (map.containsKey(key)) {
if (get(key) != -1) {
3
Node temp = map.get(key);
temp.value = value;
3
return;
}
if (map.size() == capacity) {
Node temp = tail.prev;
map.remove(temp.key);
tail.prev = temp.prev;
temp.prev.next = tail;
}
Node newNode = new Node(key, value);
map.put(key, newNode);
moveAfterHead(newNode);
}
private void moveAfterHead(Node node) {
node.next = head.next;
head.next.prev = node;
node.prev = head;
//2 head.next = node.next;
head.next = node;
}
}