回答

分析

标准实现:使用双向链表+Map的组合

见参考资料。

JS 特有的简单实现,利用 Map 中 key 的有序性

  1. // JS特有的最简单实现,利用Map中key的有序性
  2. class LRUCache {
  3. constructor(capacity: number) {
  4. this.capacity = capacity;
  5. this.dataMap = new Map();
  6. }
  7. // 数据存储,使用map,并且利用到map中key的有序性
  8. dataMap: Map<any, any> = new Map();
  9. // 缓存个数
  10. capacity: number;
  11. // 时间复杂度:O(1)
  12. // 有额外的空间损失
  13. get(key: any) {
  14. // 仅在有此key的时候重写
  15. if (this.dataMap.has(key)) {
  16. // get算作使用一次,利用map中key的有序特性,重写一次key,则将key置于map的最后
  17. let result = this.dataMap.get(key);
  18. this.dataMap.delete(key);
  19. this.dataMap.set(result, key);
  20. return result;
  21. }
  22. }
  23. // 时间复杂度:O(n),因为Map.keys()在底层需要遍历,虽然实现起来挺快的
  24. put(key: any, value: any) {
  25. // 检查是否已满
  26. if (this.dataMap.size >= this.capacity) {
  27. let deleteKey = [...this.dataMap.keys()][0];
  28. this.dataMap.delete(deleteKey);
  29. }
  30. // 放入
  31. this.dataMap.set(key, value);
  32. }
  33. }
  34. // test
  35. const cache = new LRUCache(2);
  36. cache.put(1, "a");
  37. cache.put(2, "b");
  38. console.log(cache.get(1)); // return 'a'
  39. cache.put(3, "c"); // remove 2 from cache
  40. console.log(cache.get(2)); // return null

参考资料

  1. 每周算法-缓存置换算法 [https://juejin.im/post/6844903928945967111]