「✍ 算法 - LRU」

79 阅读1分钟

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 }