norangmangto / coding_study

Summary of my coding study with leetcode, hackerrank and so on.
0 stars 0 forks source link

LRU Cache #17

Open norangmangto opened 6 years ago

norangmangto commented 6 years ago

https://leetcode.com/problems/lru-cache/description/

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

Follow up:
Could you do both operations in O(1) time complexity?

Example:

LRUCache cache = new LRUCache( 2 /* capacity */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // returns 1
cache.put(3, 3);    // evicts key 2
cache.get(2);       // returns -1 (not found)
cache.put(4, 4);    // evicts key 1
cache.get(1);       // returns -1 (not found)
cache.get(3);       // returns 3
cache.get(4);       // returns 4
norangmangto commented 6 years ago

My solution is below.

class LRUCache:

    def __init__(self, capacity):
        """
        :type capacity: int
        """
        self.capacity = capacity
        self.queue = []
        self.data = {}

    def get(self, key):
        """
        :type key: int
        :rtype: int
        """
        if key not in self.data:
            return -1
        self._update_queue(key)
        return self.data[key]

    def put(self, key, value):
        """
        :type key: int
        :type value: int
        :rtype: void
        """
        if key in self.data:
            self.data[key] = value
            self._update_queue(key)
        else:
            if self._is_full():
                poped_key = self.queue.pop(0)
                del self.data[poped_key]
            self.queue.append(key)
            self.data[key] = value

    def _update_queue(self, key):
        self.queue.append(self.queue.pop(self.queue.index(key)))

    def _is_full(self):
        return len(self.queue) == self.capacity

# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
norangmangto commented 6 years ago

To solve the follow up question (do both operations in O(1) time complexity), I found this article.

I found that I have to use LinkedHashMap used in Java.