Design
//hash表 + 双向链表(头代表最新,尾代表老)
function ListNode(key, value) {
this.key = key
this.value = value
this.next = null
this.prev = null
}
var LRUCache = function (capacity) {
// 缓存容量
this.capacity = capacity
// 哈希表 key -> ListNode
this.hashTable = {}
// 缓存数目
this.count = 0
// 虚拟头尾
this.dummyHead = new ListNode()
this.dummyTail = new ListNode()
this.dummyHead.next = this.dummyTail
this.dummyTail.prev = this.dummyHead
}
//若哈希表中没有对应值,返回-1。若存在节点,刷新它的位置,移动到链表头部,返回该节点值
LRUCache.prototype.get = function (key) {
const node = this.hashTable[key]
if (!node) return -1
this.moveToHead(node)
return node.value
}
LRUCache.prototype.moveToHead = function (node) {
//从链表中删除该节点
this.removeFromList(node)
//将该节点添加到链表的头部
this.addToHead(node)
}
LRUCache.prototype.removeFromList = function (node) {
const prev = node.prev
const next = node.next
prev.next = next
next.prev = prev
}
LRUCache.prototype.addToHead = function (node) {
//插入到虚拟头结点和真实头结点之间,注意顺序,先链接node,再调整指针
//node的prev指针指向虚拟头结点
node.prev = this.dummyHead
//node的next指针指向原来的真实头结点
node.next = this.dummyHead.next
//原来的真实头结点的prev指向node
this.dummyHead.next.prev = node
//虚拟头结点的next指向node
this.dummyHead.next = node
}
//对于新数据,创建新节点,存入哈希表,并添加到链表头部(最不优先被淘汰),检查是否超容,决定是否剔除"老家伙"
//对于已有数据,更新数据值,刷新节点位置
LRUCache.prototype.put = function (key, value) {
const node = this.hashTable[key]
//insert
if (!node) {
const newNode = new ListNode(key, value)
this.hashTable[key] = newNode
this.addToHead(newNode)
this.count++
//check capacity
if (this.count > this.capacity) {
//删除"老家伙",将它从链表尾部删除
const tailNode = this.dummyTail.prev
this.removeFromList(tailNode)
delete this.hashTable[tailNode.key]
this.count--
}
//update
} else {
node.value = value
this.moveToHead(node)
}
}Last updated