1. # 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
    2. #
    3. #
    4. #
    5. # 实现 LRUCache 类:
    6. #
    7. #
    8. # LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
    9. # int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
    10. # void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上
    11. # 限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
    12. #
    13. #
    14. #
    15. #
    16. #
    17. #
    18. # 进阶:你是否可以在 O(1) 时间复杂度内完成这两种操作?
    19. #
    20. #
    21. #
    22. # 示例:
    23. #
    24. #
    25. # 输入
    26. # ["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
    27. # [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
    28. # 输出
    29. # [null, null, null, 1, null, -1, null, -1, 3, 4]
    30. #
    31. # 解释
    32. # LRUCache lRUCache = new LRUCache(2);
    33. # lRUCache.put(1, 1); // 缓存是 {1=1}
    34. # lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
    35. # lRUCache.get(1); // 返回 1
    36. # lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
    37. # lRUCache.get(2); // 返回 -1 (未找到)
    38. # lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
    39. # lRUCache.get(1); // 返回 -1 (未找到)
    40. # lRUCache.get(3); // 返回 3
    41. # lRUCache.get(4); // 返回 4
    42. #
    43. #
    44. #
    45. #
    46. # 提示:
    47. #
    48. #
    49. # 1 <= capacity <= 3000
    50. # 0 <= key <= 3000
    51. # 0 <= value <= 104
    52. # 最多调用 3 * 104 次 get 和 put
    53. #
    54. # Related Topics 设计
    55. # 👍 1039 👎 0
    56. # leetcode submit region begin(Prohibit modification and deletion)
    57. class Node(object):
    58. def __init__(self, key=0, value=0):
    59. self.key = key
    60. self.value = value
    61. self.pre = None
    62. self.next = None
    63. class LRUCache(object):
    64. def __init__(self, capacity):
    65. """
    66. :type capacity: int
    67. """
    68. self.cache = dict()
    69. self.capacity = capacity
    70. self.size = 0
    71. self.head = Node()
    72. self.tail = Node()
    73. self.head.next = self.tail
    74. self.tail.pre = self.head
    75. def get(self, key):
    76. """
    77. :type key: int
    78. :rtype: int
    79. """
    80. if key in self.cache:
    81. node = self.cache[key]
    82. self.moveToHead(node)
    83. return node.value
    84. else:
    85. return -1
    86. def put(self, key, value):
    87. """
    88. :type key: int
    89. :type value: int
    90. :rtype: None
    91. """
    92. if key in self.cache:
    93. node = self.cache[key]
    94. node.value = value
    95. self.moveToHead(node)
    96. else:
    97. node = Node(key, value)
    98. self.cache[key] = node
    99. self.addToHead(node)
    100. self.size += 1
    101. if self.size > self.capacity:
    102. removed = self.removeTail()
    103. self.cache.pop(removed.key)
    104. self.size -= 1
    105. def addToHead(self, node):
    106. node.pre = self.head
    107. node.next = self.head.next
    108. self.head.next.pre = node
    109. self.head.next = node
    110. def removeNode(self, node):
    111. node.pre.next = node.next
    112. node.next.pre = node.pre
    113. def moveToHead(self, node):
    114. self.removeNode(node)
    115. self.addToHead(node)
    116. def removeTail(self):
    117. node = self.tail.pre
    118. self.removeNode(node)
    119. return node
    120. # Your LRUCache object will be instantiated and called as such:
    121. # obj = LRUCache(capacity)
    122. # param_1 = obj.get(key)
    123. # obj.put(key,value)
    124. # leetcode submit region end(Prohibit modification and deletion)
    125. obj = LRUCache(2)
    126. obj.put(1, 1)
    127. obj.put(2, 2)
    128. obj.get(1)
    129. obj.put(3, 3)
    130. print(obj.get(2))