Q:运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
实现 LRUCache 类:
- LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
- int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
- void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
/**
* Class LRU
* @param {number} capacity Map的最大容量
*/
class LRUCache {
cache: Map<number | string, unknown>;
capacity: number;
constructor(capacity: number) {
this.cache = new Map();
this.capacity = capacity;
}
get(key: number) {
if (this.cache.has(key)) {
let val = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, val);
return val;
}
// 找不到返回-1
return -1;
}
put(key: number | string, val: unknown) {
// key已经存在
if (this.cache.has(key)) {
// 提升 - 先删掉
this.cache.delete(key);
} else if (this.cache.size >= this.capacity) {
// 若已经到达最大限制,先淘汰一个最久没有使用的(队头)
// this.cache.keys()每次会返回一个新的Iterator, next()指向map第一个元素
this.cache.delete(this.cache.keys().next().value);
} else {
// key不存在,cache数量也没有达到上限
// 啥也不干
}
this.cache.set(key, val);
}
}
关于this.cache.key().next()
let map = new Map();
map.set(1, "i am 1");
map.set(2, "i am 2");
map.set(3, "i am 3");
// 每次调用keys()都返回一个新的迭代器,所以每次next()都指向第一个元素
console.log(map.keys().next()); // { value: i am 1, done: false }
console.log(map.keys().next()); // { value: i am 1, done: false }
console.log(map.keys().next()); // { value: i am 1, done: false }
console.log("================================");
let it = map.keys(); // 使用同一个迭代器引用
console.log(it.next()); // { value: i am 1, done: false }
console.log(it.next()); // { value: i am 2, done: false }
console.log(it.next()); // { value: i am 3, done: false }
console.log(it.next()); // { value: undefied, done: false }