Skip to content

146. LRU Cache

题目

Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.

Implement the LRUCache class:

  • LRUCache(int capacity) Initialize the LRU cache with positive size capacity.
  • int get(int key) Return the value of the key if the key exists, otherwise return -1.
  • void put(int key, int value) Update the value of the key if the key exists. Otherwise, add the key-value pair to the cache. If the number of keys exceeds the capacity from this operation, evict the least recently used key.

The functions get and put must each run in O(1) average time complexity.

 

Example 1:

Input
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
Output
[null, null, null, 1, null, -1, null, -1, 3, 4]

Explanation
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // cache is {1=1}
lRUCache.put(2, 2); // cache is {1=1, 2=2}
lRUCache.get(1);    // return 1
lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3}
lRUCache.get(2);    // returns -1 (not found)
lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3}
lRUCache.get(1);    // return -1 (not found)
lRUCache.get(3);    // return 3
lRUCache.get(4);    // return 4

 

Constraints:

  • 1 <= capacity <= 3000
  • 0 <= key <= 104
  • 0 <= value <= 105
  • At most 2 * 105 calls will be made to get and put.
Related Topics
  • 设计
  • 哈希表
  • 链表
  • 双向链表

  • 👍 3515
  • 👎 0
  • 思路一: OrderedDict

    hash_map + orderedDict 完成对 LRU 的操作

    • od.move_to_end() 将 dict 到的元素排列到最后

    解法

    python
    class LRUCache:
    
        def __init__(self, capacity: int):
            self.capacity = capacity
            self.cache = OrderedDict()
    
    
        def get(self, key: int) -> int:
            if not key in self.cache:
                return -1
    
            self.cache.move_to_end(key)
            return self.cache[key]
    
        def put(self, key: int, value: int) -> None:
    
            if key in self.cache:
                self.cache.move_to_end(key)
    
            self.cache[key] = value
    
            if len(self.cache) > self.capacity:
                self.cache.popitem(last=False)

    复杂度分析

    • 时间复杂度 O(1)
    • 空间复杂度 O(N)
    py
    # leetcode submit region begin(Prohibit modification and deletion)
    from collections import OrderedDict
    
    class LRUCache:
    
        def __init__(self, capacity: int):
            self.capacity = capacity
            self.cache = OrderedDict()
    
    
        def get(self, key: int) -> int:
            if not key in self.cache:
                return -1
    
            self.cache.move_to_end(key)
            return self.cache[key]
    
        def put(self, key: int, value: int) -> None:
    
            if key in self.cache:
                self.cache.move_to_end(key)
    
            self.cache[key] = value
    
            if len(self.cache) > self.capacity:
                self.cache.popitem(last=False)
    
    
    
    
    
    # Your LRUCache object will be instantiated and called as such:
    # obj = LRUCache(capacity)
    # param_1 = obj.get(key)
    # obj.put(key,value)
    # leetcode submit region end(Prohibit modification and deletion)

    思路二:hashmap + doubly linked list