大疆笔试遇到这道题,记录一下:
/**
* @param {number} capacity
*/
var LRUCache = function(capacity) {
this.map = new Map();
this.capacity = capacity;
this.timers = new Map(); // 用于存储定时器
};
/**
* @param {number} key
* @return {number}
*/
LRUCache.prototype.get = function(key) {
if (!this.map.has(key)) return -1;
let temp = this.map.get(key);
this.map.delete(key);
this.map.set(key, temp);
return temp;
};
/**
* @param {number} key
* @param {number} value
* @param {number} [ttl] - 过期时间(毫秒)
* @return {void}
*/
LRUCache.prototype.put = function(key, value, ttl) {
if (this.map.has(key)) {
this.map.delete(key);
clearTimeout(this.timers.get(key)); // 清除旧的定时器
}
this.map.set(key, value);
if (ttl !== undefined) {
const timer = setTimeout(() => {
this.map.delete(key);
this.timers.delete(key);
}, ttl);
this.timers.set(key, timer);
}
if (this.map.size > this.capacity) {
const oldestKey = [...this.map.keys()][0];
this.map.delete(oldestKey);
if (this.timers.has(oldestKey)) {
clearTimeout(this.timers.get(oldestKey));
this.timers.delete(oldestKey);
}
}
};
// 测试
var cache = new LRUCache(2);
cache.put(1, 1, 5000); // 设置 key 1 的过期时间为 5 秒
cache.put(2, 2);
console.log(cache.get(1)); // 返回 1
setTimeout(() => {
console.log(cache.get(1)); // 返回 -1,因为 key 1 已经过期
}, 6000);
cache.put(3, 3); // 这个操作会使 key 2 被移除
console.log(cache.get(2)); // 返回 -1,因为 key 2 被移除
console.log(cache.get(3)); // 返回 3
- 新增 timers 属性
用于存储每个键的定时器。 - 修改 put 方法
如果键已经存在,先删除旧的键并清除旧的定时器。
如果设置了 ttl(过期时间),使用 setTimeout 创建一个定时器,当时间到达时自动删除该键。
如果缓存超过容量,删除最老的键,并清除其定时器(如果存在)。