2018-10-23/24 LRU Cache [H]

  1. LRU Cache = LC: 146

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

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(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.

class LinkedNode:
    def __init__(self, key=None, value=None, next=None):
        self.key = key
        self.value = value
        self.next = next


class LRUCache:
    """
    @param: capacity: An integer
    """
    def __init__(self, capacity):
        self.hash = {}
        self.head = LinkedNode() # dummy
        self.tail = self.head
        self.capacity = capacity

    # change "head -> node1 -> node2"
    # to "head -> node1 -> node2 -> node3"
    def push_back(self, node):
        self.hash[node.key] = self.tail
        self.tail.next = node
        self.tail = node
    
    # change "head -> node1 -> node2 -> node3"
    # to "head -> node2 -> node3"
    def pop_front(self,):
        del self.hash[self.head.next.key] # delete a reference, not node
        self.hash[self.head.next.next.key] = self.head
        self.head.next = self.head.next.next
    
    # change "head -> node -> node2"
    # to "head -> node2 -> node"
    def move_to_back(self, prev):
        node = prev.next
        if node == self.tail:
            return
        prev.next = node.next
        self.hash[node.next.key] = prev
        node.next = None
        self.push_back(node)
    
    """
    @param: key: An integer
    @return: An integer
    """
    def get(self, key):
        if key in self.hash:
            self.move_to_back(self.hash[key])
            return self.hash[key].next.value
        return -1

    """
    @param: key: An integer
    @param: value: An integer
    @return: nothing
    """
    def set(self, key, value):
        if key in self.hash:
            self.move_to_back(self.hash[key])
            self.hash[key].next.value = value
        else:
            self.push_back(LinkedNode(key, value))
            if len(self.hash) > self.capacity:
                self.pop_front()

Time: O(1) for all
Space: ``

Notes:

  1. I need to understand WHAT is LRU cache:
    Least Recently Used - The data you visited in the last round, you will very probably visit it in the next round.
  2. Use linked list in this problem, because I want to have pop_front(), push_back() and move_to_back().
    • Linked list takes least time, O(1), but not for move_to_back(). Therefore, use hash map(cache key, linked list node) to look up nodes in O(1) time
    • If I need to remove a node, I need to know its prev node. Therefore, Doubly linked list is needed. Or, use hash map(cache key, prev node) instead. Hash map works 1) adding another property of linked, prev. 2) easy to edit value of node.
  3. Learn to write LinkedNode() in Python.
    Remember to initialize all values to be None
def __init__(self, key=None, value=None, next=None):
  1. Relate this problem to First Unique Character in a String. A follow-up of this problem is data stream.

Extension:

  1. Python Tricks, use OrderedDict which has the same concept. Similar to LinkedHashMap in Java.
from collections import OrderedDict

class LRUCache:
    def __init__(self, capacity):
        self.capacity = capacity
        self.cache = OrderedDict()

    def get(self, key):
        if key not in self.cache:
            return -1
        value = self.cache.pop(key) # take it out
        self.cache[key] = value # insert it back
        return value
        
    def set(self, key, value):
        if key in self.cache:
            self.cache.pop(key)
        elif len(self.cache) == self.capacity:
            ## last = True => FILO
            ## last = False => FIFO
            self.cache.popitem(last = False) # just pop head or tail, no key input
        self.cache[key] = value

你可能感兴趣的:(2018-10-23/24 LRU Cache [H])