LeetCode-其它

1. BM100 设计LRU缓存结构

设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设大小为 k ,操作次数是 n ,并有如下两个功能

1. set(key, value):将记录(key, value)插入该结构

2. get(key):返回key对应的value值

提示:

1.某个key的set或get操作一旦发生,认为这个key的记录成了最常使用的,然后都会刷新缓存。

2.当缓存的大小超过k时,移除最不经常使用的记录。

3.输入一个二维数组与k,二维数组每一维有2个或者3个数字,第1个数字为opt,第2,3个数字为key,value

若opt=1,接下来两个整数key, value,表示set(key, value)
若opt=2,接下来一个整数key,表示get(key),若key未出现过或已被移除,则返回-1
对于每个opt=2,输出一个答案

4.为了方便区分缓存里key与value,下面说明的缓存里key用""号包裹

import sys
class Solution:
    def __init__(self,k):
        self.k = k
        self.out=[]
        self.dict_lru =dict()
        self.list_lru = []
         
    def LRU(self , operators , k ):
        self.k =k
        for o in operators:
            if o[0] ==1:
                self.set(o[1],o[2])
            else:
                self.out.append(self.get(o[1]))
        return self.out
     
    def get(self,key):
        if key in self.dict_lru:
            self.list_lru.remove(key)
            self.list_lru.append(key)
            return self.dict_lru[key]
        return -1
     
    def set(self,key,value):
        if key in self.dict_lru:
            self.list_lru.remove(key)
            self.list_lru.append(key)
        else:
            self.list_lru.append(key)
        self.dict_lru[key]=value
        if len(self.list_lru)>self.k:
            self.dict_lru.pop(self.list_lru.pop(0))

for line in sys.stdin.readlines():
    line = line.strip()
    line = line.replace(' ', '')
    a = line.split(']],')
    k = int(a[1])
    res = []
    s = Solution(k)
    for item in a[0][2:].split('],['):
        m = item.split(',')
        if m[0] == '1':
            s.set(int(m[1]), int(m[2]))
        else:
            res.append(s.get(int(m[1])))
    print(str(res).replace(' ', ''))
# write code here
        

二、设计LFU缓存结构

一个缓存结构需要实现如下功能。

  • set(key, value):将记录(key, value)插入该结构
  • get(key):返回key对应的value值

但是缓存结构中最多放K条记录,如果新的第K+1条记录要加入,就需要根据策略删掉一条记录,然后才能把新记录加入。这个策略为:在缓存结构的K条记录中,哪一个key从进入缓存结构的时刻开始,被调用set或者get的次数最少,就删掉这个key的记录;

如果调用次数最少的key有多个,上次调用发生最早的key被删除

这就是LFU缓存替换算法。实现这个结构,K作为参数给出

数据范围:0 < k \le 10^50<k≤105,|val| \le 2 \times 10^9∣val∣≤2×109

要求:get和set的时间复杂度都是 O(logn)O(logn),空间复杂度是 O(n)O(n)

若opt=1,接下来两个整数x, y,表示set(x, y)
若opt=2,接下来一个整数x,表示get(x),若x未出现过或已被移除,则返回-1
 

对于每个操作2,返回一个答案

class Node:
    def __init__(self, cnt=1, key=None, val=None):
        self.key = key
        self.val = val
        self.prev = None
        self.next = None
        self.cnt = cnt
        
class DLL:
    def __init__(self):
        self.head = Node()
        self.tail = Node()
        self.head.next = self.tail
        self.tail.prev = self.head
    def addInFront(self, node):
        node.prev = self.head
        node.next = self.head.next
        self.head.next = node
        node.next.prev = node
    def remove(self, node):
        node.prev.next = node.next
        node.next.prev = node.prev
        

class LFUCache(object):

    def __init__(self, capacity):
        """
        :type capacity: int
        """
        self.nKey = 0
        self.capacity = capacity
        self.dll = DLL()
        self.headerNodes = dict()
        self.dataNodes = dict()
        
        headerNode = Node(key=1, val=DLL(), cnt=0)
        self.headerNodes[1] = headerNode
        self.dll.addInFront(headerNode)
        
    
    def touch(self, node):
        self.headerNodes[node.cnt].val.remove(node)
        self.headerNodes[node.cnt].cnt -= 1
        node.cnt += 1
        freq = node.cnt
        if freq not in self.headerNodes:
            headerNode = Node(key=freq, val=DLL(), cnt=0)
            self.dll.addInFront(headerNode)
            self.headerNodes[freq] = headerNode
        self.headerNodes[freq].val.addInFront(node)
        self.headerNodes[freq].cnt += 1
    
    def get(self, key):
        """
        :type key: int
        :rtype: int
        """
        if self.capacity == 0:
            return -1
        if key in self.dataNodes:
            node = self.dataNodes[key]
            self.touch(node)
            return node.val
        else:
            return -1

    def put(self, key, value):
        """
        :type key: int
        :type value: int
        :rtype: None
        """
        if self.capacity == 0:
            return
        if key in self.dataNodes:
            node = self.dataNodes[key]
            self.touch(node)
            node.val = value
        else:
            if self.nKey == self.capacity:
                headerNode = self.dll.tail.prev
                while headerNode.cnt == 0:
                    headerNode = headerNode.prev
                nodeToRemove = headerNode.val.tail.prev
                headerNode.val.remove(nodeToRemove)
                headerNode.cnt -= 1
                del self.dataNodes[nodeToRemove.key]
                self.nKey -= 1
            node = Node(key=key, val=value)
            self.headerNodes[1].val.addInFront(node)
            self.headerNodes[1].cnt += 1
            self.dataNodes[key] = node
            self.nKey += 1
            
class Solution:
    def LFU(self , operators , k ):
        # write code here
        lfu = LFUCache(k)
        res = []
        for op in operators:
            if op[0] == 1:
                lfu.put(op[1], op[2])
            else:
                res.append(lfu.get(op[1]))
        return res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值