-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
法一:Map+双指针
function Node(key, value) {
this.key = key;
this.value = value;
this.pre = null;
this.next = null;
}
function DoubleLinkedList() {
this.head = new Node(0, 0);
this.tail = new Node(0, 0);
this.head.next = this.tail;
this.tail.pre = this.head;
}
DoubleLinkedList.prototype.addNodeToFirst = function (node) {
node.pre = this.head;
node.next = this.head.next;
this.head.next.pre = node;
this.head.next = node;
}
DoubleLinkedList.prototype.deleteNode = function (node) {
node.pre.next = node.next;
node.next.pre = node.pre;
return node.key;
}
DoubleLinkedList.prototype.deleteLastNode = function () {
if(this.head.next == this.tail) return -1;
return this.deleteNode(this.tail.pre);
}
/**
* @param {number} capacity
*/
var LRUCache = function(capacity) {
this.map = new Map();
this.cache = new DoubleLinkedList();
this.capacity = capacity;
};
/**
* @param {number} key
* @return {number}
*/
LRUCache.prototype.get = function(key) {
if(!this.map.has(key)) return -1;
// 更新缓存中的key
const value = this.map.get(key).value;
this.put(key, value);
return value;
};
/**
* @param {number} key
* @param {number} value
* @return {void}
*/
LRUCache.prototype.put = function(key, value) {
const newNode = new Node(key, value);
if(!this.map.has(key)){
if(this.map.size == this.capacity){ // 如果存储的数据已到最大容量
let oldKey = this.cache.deleteLastNode();
this.map.delete(oldKey);
}
this.map.set(key, newNode);
this.cache.addNodeToFirst(newNode);
}else{
// 更新list中对应节点为最新使用过的
this.cache.deleteNode(this.map.get(key));
this.cache.addNodeToFirst(newNode);
// 更新map中对应节点为最新使用过的
this.map.set(key, newNode);
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* var obj = new LRUCache(capacity)
* var param_1 = obj.get(key)
* obj.put(key,value)
*/
法二:巧用 Map 数据结构
首先明确一个性质,Map 这个 ES6 新增数据结构是 有序的,即不仅可以存储键值对(关键字-值),还可以通过 delete 和 set 的 API 对> 数据进行更新,最后 set 的数据默认在 Map 的末尾(最新)
因此利用好上面的性质,这题其实非常容易了,对于题目的 第二点 和 第三点 要求,在每次 get 和 put 已存在队列中的值,或新增值,直接 delete 删掉后,再 set 进行更新到 Map 最后即可(最新)
/**
* @param {number} capacity
*/
var LRUCache = function(capacity) {
this.map = new Map();
this.capacity = capacity;
};
/**
* @param {number} key
* @return {number}
*/
LRUCache.prototype.get = function(key) {
if(this.map.has(key)){
let value = this.map.get(key);
this.map.delete(key); // 删除后,再 set ,相当于更新到 map 最后一位
this.map.set(key, value);
return value
} else {
return -1
}
};
/**
* @param {number} key
* @param {number} value
* @return {void}
*/
LRUCache.prototype.put = function(key, value) {
// 如果已有,那就要更新,即要先删了再进行后面的 set
if(this.map.has(key)){
this.map.delete(key);
this.map.set(key, value);
}else{
// put 后判断是否超载
if(this.map.size == this.capacity){
this.map.delete(this.map.keys().next().value); // 删除Map第一个元素
}
this.map.set(key, value);
}
};