1. // 双向链表节点
    2. var LinkNode = function (key, val) {
    3. if(!(this instanceof LinkNode)) {
    4. return new LinkNode(key, val)
    5. }
    6. this.key = key;
    7. this.val = val;
    8. }
    9. // 双向链表
    10. var DoubleLink = function() {
    11. this.head = new LinkNode(0, 0)
    12. this.tail = new LinkNode(0, 0)
    13. this.head.next = this.tail
    14. this.tail.prev = this.head
    15. this.size = 0
    16. }
    17. // // 在链表尾部添加节点 x,时间 O(1)
    18. DoubleLink.prototype.addLast = function(node) {
    19. node.prev = this.tail.prev
    20. node.next = this.tail
    21. this.tail.prev.next = node
    22. this.tail.prev = node
    23. ++this.size
    24. }
    25. // 删除链表中的 x 节点(x 一定存在)
    26. // 由于是双链表且给的是目标 Node 节点,时间 O(1)
    27. DoubleLink.prototype.remove = function (node) {
    28. node.prev.next = node.next;
    29. node.next.prev = node.prev;
    30. --this.size;
    31. }
    32. // 删除链表中第一个节点,并返回该节点,时间 O(1)
    33. DoubleLink.prototype.removeFirst = function() {
    34. if(this.head.next === this.tail) {
    35. return null
    36. }
    37. let first = this.head.next
    38. this.remove(first)
    39. return first
    40. }
    41. // 返回链表长度,时间 O(1)
    42. DoubleLink.prototype.getSize = function () {
    43. return this.size;
    44. }
    45. /**
    46. * @param {number} capacity
    47. */
    48. var LRUCache = function (capacity) {
    49. this.map = new Map();
    50. this.cache = new DoubleLink();
    51. //最大容量
    52. this.cap = capacity;
    53. };
    54. /**
    55. * @param {number} key
    56. * @return {number}
    57. */
    58. LRUCache.prototype.get = function (key) {
    59. if (!this.map.has(key)) {
    60. return -1;
    61. }
    62. // 将该数据提升为最近使用的
    63. this.makeRecently(key);
    64. return this.map.get(key).val;
    65. };
    66. /**
    67. * @param {number} key
    68. * @param {number} value
    69. * @return {void}
    70. */
    71. LRUCache.prototype.put = function (key, value) {
    72. if (this.map.has(key)) {
    73. // 删除旧的数据
    74. this.deleteKey(key);
    75. // 新插入的数据为最近使用的数据
    76. this.addRecently(key, value);
    77. return;
    78. }
    79. if (this.cap === this.cache.getSize()) {
    80. // 删除最久未使用的元素
    81. this.removeLeastRecently();
    82. }
    83. // 添加为最近使用的元素
    84. this.addRecently(key, value);
    85. };
    86. /**
    87. * Your LRUCache object will be instantiated and called as such:
    88. * var obj = new LRUCache(capacity)
    89. * var param_1 = obj.get(key)
    90. * obj.put(key,value)
    91. */
    92. /* 将某个 key 提升为最近使用的 */
    93. LRUCache.prototype.makeRecently = function (key) {
    94. let x = this.map.get(key);
    95. // 先从链表中删除这个节点
    96. this.cache.remove(x);
    97. // 重新插入到队尾
    98. this.cache.addLast(x);
    99. }
    100. /* 添加最近使用的元素 */
    101. LRUCache.prototype.addRecently = function (key, val) {
    102. let x = new LinkNode(key, val);
    103. // 链表尾部就是最近使用的元素
    104. this.cache.addLast(x);
    105. // 别忘了在 map 中添加 key 的映射
    106. this.map.set(key, x);
    107. }
    108. /* 删除某一个 key */
    109. LRUCache.prototype.deleteKey = function (key) {
    110. let x = this.map.get(key);
    111. // 从链表中删除
    112. this.cache.remove(x);
    113. // 从 map 中删除
    114. this.map.delete(key);
    115. }
    116. /* 删除最久未使用的元素 */
    117. LRUCache.prototype.removeLeastRecently = function () {
    118. // 链表头部的第一个元素就是最久未使用的
    119. let deletedNode = this.cache.removeFirst();
    120. // 同时别忘了从 map 中删除它的 key
    121. let deletedKey = deletedNode.key;
    122. this.map.delete(deletedKey);
    123. }