leetcode 面试题 16.25. LRU 缓存
问题描述: 设计和构建一个“最近最少使用”缓存,该缓存会删除最近最少使用的项目。缓存应该从键映射到值(允许你插入和检索特定键对应的值),并在初始化时指定最大容量。当缓存被填满时,它应该删除最近最少使用的项目。
它应该支持以下操作: 获取数据 get
和 写入数据 put
。
获取数据 get(key)
- 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value)
- 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。
示例:
LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 该操作会使得密钥 2 作废
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 该操作会使得密钥 1 作废
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4
思路: 整体设计为一个哈希链表!外面是链表,值存放在map中,(值对应链表节点)找到map对应的节点,来处理链表。
function Node(key,value,prev,next){
this.key=key||0;
this.value=value||0;
this.prev=prev||null;
this.next=next||null;
}
Node.prototype.remove_this=function(){
if(this.prev) this.prev.next=this.next;
if(this.next)this.next.prev=this.prev;
this.prev=this.next=null;
return;
}
Node.prototype.insert_prev=function(node){
node.next=this;
node.prev=this.prev;
if(this.prev)this.prev.next=node;
this.prev=node
return;
}
/**
* @param {number} capacity
*/
var LRUCache = function(capacity) {
this.capacity=capacity;
this.map=new Map()
this.tail=new Node()
this.head=new Node()
this.head.next=this.tail;
this.tail.prev=this.head;
};
/**
* @param {number} key
* @return {number}
*/
LRUCache.prototype.get = function(key) {
if(!this.map.get(key))return -1;
this.map.get(key).remove_this();//先移除掉
this.tail.insert_prev(this.map.get(key))//放到链表最后(尾部节点之前)
return this.map.get(key).value
};
/**
* @param {number} key
* @param {number} value
* @return {void}
*/
LRUCache.prototype.put = function(key, value) {
if(this.map.get(key)){
this.map.get(key).value=value;
this.map.get(key).remove_this()
}else{
this.map.set(key,new Node(key,value))
}
this.tail.insert_prev(this.map.get(key))
if(this.map.size>this.capacity){
this.map.delete(this.head.next.key)
this.head.next.remove_this();
}
return
};