LRU Cache

两道cache经典题中的一道,要求我们按照最近使用的时间来进行列表更新,且要求所有操作时间复杂度O(1),因为全部都要O(1),明显我们是需要使用哈希表的,但是因为每次操作都会更新对应的数据位置,也就是说我们必须把最近被操作过的数据放到最不可能被移除的位置去,这个操作又和栈类似,所以明显我们需要一个链表的结构来存储数据,但如果是单链表,则我们虽然可以利用哈希表快速定位,但却无法对结点前后的结点进行正确处理,所以我们需要一个双链表,同时链表的结点里既包含了key,也包含了value,这样方便我们更新时删除结点的操作,最后,凡是链表类的题,dummy node大部分情况都是需要的

class ListNode(object):
    def __init__(self, key, val):
        self.key = key
        self.val = val
        self.next = None
        self.prev = None

class LRUCache(object):

    def __init__(self, capacity):
        """
        :type capacity: int
        """
        self.cap = capacity
        self.root = ListNode('dummy', 'dummy')
        self.curCap = 0
        self.tail = self.root
        self.accesser = {}

    def get(self, key):
        """
        :type key: int
        :rtype: int
        """
        if key in self.accesser:
            node = self.accesser[key]
            if self.tail == node:
                return node.val
            self.moveToTail(node)
            return node.val

        return -1

    def put(self, key, value):
        """
        :type key: int
        :type value: int
        :rtype: void
        """
        if key in self.accesser:
            node = self.accesser[key]
            node.val = value
            if self.tail == node:
                return 
            self.moveToTail(node)
        elif self.curCap < self.cap:
            self.__newNode(key, value)
            self.curCap += 1
        else:
            self.__newNode(key, value)
            del self.accesser[self.root.next.key]
            self.root = self.root.next

    def moveToTail(self, node):
        prevNode = node.prev
        nextNode = node.next
        prevNode.next = nextNode
        nextNode.prev = prevNode
        self.tail.next = node
        node.prev = self.tail
        self.tail = self.tail.next

    def __newNode(self, key, value):
        self.tail.next = ListNode(key, value)
        self.tail.next.prev = self.tail
        self.tail = self.tail.next
        self.accesser[key] = self.tail

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

results matching ""

    No results matching ""