纯编程能力的题,只有编程没有算法,考验是否够细心
哈希表的作用是O(1)时间内检查链表中是否存在某节点
感觉我在put操作比官解更严谨一点?
class LRUCache {
// 建立双向链表结构
class DLinkedNode {
int key;
int value;
DLinkedNode pre;
DLinkedNode next;
public DLinkedNode() {
}
public DLinkedNode(int _key, int _value) {
key = _key;
value = _value;
}
}
// 当前节点数量
private int size;
// 缓存容量
private int capacity;
// 哈希表
private Map<Integer, DLinkedNode> nodeMap = new HashMap<>();
// 伪头部,伪尾部
private DLinkedNode head, tail;
public LRUCache(int capacity) {
this.size = 0;
this.capacity = capacity;
head = new DLinkedNode();
tail = new DLinkedNode();
head.next = tail;
tail.pre = head;
}
public int get(int key) {
DLinkedNode node = nodeMap.get(key);
// 如果节点不存在,返回null
if (node == null) {
return -1;
}
// 存在,把节点移动到头部,返回value
moveToHead(node);
return node.value;
}
public void put(int key, int value) {
DLinkedNode node = nodeMap.get(key);
// 如果key已经存在,更新value
if (node != null) {
node.value = value;
// 移动到头部
moveToHead(node);
// 更新哈希表
nodeMap.put(key, node);
// key不存在,插入新的node,先检查容量是否越界
} else if (size == capacity) {
// 容量不足,移除尾节点,再插入
DLinkedNode oldTail = removeTail();
node = new DLinkedNode(key, value);
// 更新哈希表
nodeMap.remove(oldTail.key);
nodeMap.put(key, node);
addToHead(node);
} else {
// 容量足够,直接在头部插入
node = new DLinkedNode(key, value);
addToHead(node);
// 更新哈希表
nodeMap.put(key, node);
// 记得更新size
size++;
}
}
private void moveToHead(DLinkedNode node) {
if (node.pre != head) {
// 断开node的前后节点
node.pre.next = node.next;
node.next.pre = node.pre;
// 把node插入头部
addToHead(node);
}
}
private void addToHead(DLinkedNode node) {
node.pre = head;
node.next = head.next;
node.next.pre = node;
head.next = node;
}
private DLinkedNode removeTail() {
DLinkedNode oldTail = tail.pre;
oldTail.pre.next = tail;
tail.pre = oldTail.pre;
oldTail.pre = null;
oldTail.next = null;
return oldTail;
}
}
/**
* 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);
*/