LeetCode - LRU Cache

01.08.2021

小白一枚,文章仅当日记本记录学习进度 ;)

如被浏览,请多多指教,非常感谢大家纠错与建议!

(因留学顺便练习英语,所以部分用英文笔记,并无他意)

cache : in memory that holds the most recent result;  LRU is a common cache algorithm

1. When you see put and get, you shold think of Hashmap immediately which has instant get and put operations

2. When we use something, we want to move it to the front of the cache. We have to use a linked list because Deletions and Intertions are contant time , also because we need ordering becasue Hashmap are unordered, we need a linked list to keep a structure so that we can put things in constant time , most recently used thing will be at the front of our list right after the head , head.next = new_node, when we delete things it will pop it off the tail

Solution 1 - Hashmap + Double linked list (Python)

class Node:
    def __init__(self, key=0, value=0):
        self.value = value
        self.key = key
        self.prev = None
        self.next = None


class LRUCache:
    def __init__(self, capacity: int):
        self.cache = dict()
        self.capacity = capacity
        self.head = Node()  # pseudo head node
        self.tail = Node()  # pseudo tail node
        self.head.next = self.tail
        self.tail.prev = self.head
        self.size = 0

    def get(self, key: int):
        if key not in self.cache:
            return -1
        node = self.cache[key]
        self.moveToHead(node)
        return node.value

    def put(self, key, value):
        if key not in self.cache:
            node = Node(key, value) # create a new node if it does't exist
            self.cache[key] = node # add it to Hashmap
            self.addToHead(node) # add it to the head
            self.size += 1
            if self.size > self.capacity:
                removedNode = self.removeTail() # delete the tail node from linked list
                self.cache.pop(removedNode.key) # delete the pair from Hashmap
                self.size -= 1
        else:
            node = self.cache[key]
            node.value = value
            self.moveToHead(node)

    def moveToHead(self, node):
        self.removeNode(node)
        self.addToHead(node)

    def removeTail(self):
        node = self.tail.prev
        self.removeNode(node)
        return node

    def removeNode(self, node):
        node.prev.next = node.next
        node.next.prev = node.prev

    def addToHead(self, node):
        node.prev = self.head
        node.next = self.head.next
        self.head.next.prev = node
        self.head.next = node

Solution 2 - OrderdDict (Python)

Leetcode给的solution,不知道OrderedDict可能想不出来。。。

from collections import OrderedDict
class LRUCache(OrderedDict):

    def __init__(self, capacity):
        """
        :type capacity: int
        """
        self.capacity = capacity

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

    def put(self, key, value):
        """
        :type key: int
        :type value: int
        :rtype: void
        """
        if key in self:
            self.move_to_end(key)
        self[key] = value
        if len(self) > self.capacity:
            self.popitem(last = False)

线性:内存连续,可以通过index访问

链式:不连续,不能通过index访问,追加元素方便,遍历会麻烦

1.单链表 linked list - 通过指针(pointer)把节点(node)串起来;root node, head node, tail node; 缺点是remove时间复杂度为O(n),只能单向遍历

2.双链表 double linked list - prev, value, next; remove时间复杂度为O(1), 可以双向遍历

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值