如何实现一个 LRU

本文阅读 1 分钟
首页 知识库 正文

用双向链表+哈希。

  1. /**
  2. * @param {number} capacity
  3. */
  4. var LRUCache = function (capacity) {
  5. this.capacity = capacity;
  6. this.map = new Map();
  7. this.cache = new DoubleList();
  8. };
  9. class Node {
  10. constructor(k, val) {
  11. this.k = k;
  12. this.val = val;
  13. this.pre = null;
  14. this.next = null;
  15. }
  16. }
  17. class DoubleList {
  18. constructor() {
  19. this.size = 0;
  20. this.head = new Node(0, 0);
  21. this.tail = new Node(0, 0);
  22. this.head.next = this.tail;
  23. this.tail.pre = this.head;
  24. }
  25. addLast(x) {
  26. const { head, tail } = this;
  27. x.pre = tail.pre;
  28. x.next = tail;
  29. tail.pre.next = x;
  30. tail.pre = x;
  31. this.size++;
  32. }
  33. remove(x) {
  34. x.pre.next = x.next;
  35. x.next.pre = x.pre;
  36. this.size--;
  37. }
  38. removeFirst() {
  39. const { head, tail } = this;
  40. if (head.next === tail) return null;
  41. let first = head.next;
  42. this.remove(first);
  43. return first;
  44. }
  45. }
  46. /**
  47. * @param {number} key
  48. * @return {number}
  49. */
  50. LRUCache.prototype.get = function (key) {
  51. const { cache, map } = this;
  52. if (map.has(key)) {
  53. let x = map.get(key);
  54. cache.remove(x);
  55. cache.addLast(x);
  56. return map.get(key).val;
  57. } else {
  58. return -1;
  59. }
  60. };
  61. /**
  62. * @param {number} key
  63. * @param {number} value
  64. * @return {void}
  65. */
  66. LRUCache.prototype.put = function (key, value) {
  67. const { cache, map, size } = this;
  68. const addRecently = function (key, value) {
  69. let x = new Node(key, value);
  70. cache.addLast(x);
  71. map.set(key, x);
  72. };
  73. if (map.has(key)) {
  74. let x = map.get(key);
  75. cache.remove(x);
  76. map.delete(key);
  77. addRecently(key, value);
  78. } else {
  79. if (cache.size === this.capacity) {
  80. let x = cache.removeFirst();
  81. map.delete(x.k);
  82. }
  83. addRecently(key, value);
  84. }
  85. };

Map 的巧妙使用 map 放入数据是按顺序的,最新放入的数据在迭代器最后 而且 map 的 entries 方法,还有 keys 方法,会返回一个迭代器,迭代器调用 next 也是顺序返回,所以返回第一个的值就是最老的,找到并删除即可。

  1. /**
  2. * @param {number} capacity
  3. */
  4. var LRUCache = function (capacity) {
  5. this.capacity = capacity;
  6. this.map = new Map();
  7. };
  8. /**
  9. * @param {number} key
  10. * @return {number}
  11. */
  12. LRUCache.prototype.get = function (key) {
  13. const map = this.map;
  14. let val = map.get(key);
  15. if (val !== undefined) {
  16. map.delete(key);
  17. map.set(key, val);
  18. return val;
  19. } else {
  20. return -1;
  21. }
  22. };
  23. /**
  24. * @param {number} key
  25. * @param {number} value
  26. * @return {void}
  27. */
  28. LRUCache.prototype.put = function (key, value) {
  29. const { map, capacity } = this;
  30. if (map.has(key)) map.delete(key);
  31. map.set(key, value);
  32. if (map.size > capacity) {
  33. map.delete(map.entries().next().value[0]);
  34. }
  35. };
解压密码: detechn或detechn.com

免责声明

本站所有资源出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。

本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户自行鉴别,做一个有主见和判断力的用户。

本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。

如何判断两个链表是否相交
« 上一篇 05-28
如何在数组中找出三个数之和为 N
下一篇 » 05-28

发表评论

惪特博客
  • 文章总数:
    18498 篇
  • 评论总数:
    53261 条
  • 标签总数:
    8869 个
  • 总浏览量:
    21731037 次
  • 最后更新:
    2天前

最多点赞

随便看看

标签TAG