LFU Cache

LFU Cache24.LFUCache中文EnglishLFU(LeastFrequentlyUsed)isafamouscacheevictionalgorithm.Foracachewithcapacityk,ifthecacheisfullandneedtoevictakeyinit,thekeywiththeleasefrequ…

大家好,欢迎来到IT知识分享网。

24. LFU Cache
中文English
LFU (Least Frequently Used) is a famous cache eviction algorithm.

For a cache with capacity k, if the cache is full and need to evict a key in it, the key with the lease frequently used will be kicked out.

Implement set and get method for LFU cache.

Example
Given capacity=3

set(2,2)
set(1,1)
get(2)
>> 2
get(1)
>> 1
get(2)
>> 2
set(3,3)
set(4,4)
get(3)
>> -1
get(2)
>> 2
get(1)
>> 1
get(4)
>> 4

维护一个 map 实现取数据时的O(1)复杂度
维护一个双链表实现更新数据时的O(1)~O(n)复杂度


        
class LFUCache:
    """ @param: capacity: An integer """
    class ListNode:
        def __init__(self, key, value, next=None, prev=None, visit_count=0):
            self.key = key
            self.value = value
            self.next = next
            self.prev = prev
            self.visit_count = visit_count
        
    def __init__(self, capacity):
        # do intialization if necessary
        self.l = 0
        self.capacity = capacity
        self.maps = { 
   }
        self.start = self.ListNode(key=None, value=None)
        self.tail = self.ListNode(key=None, value=None)
        self.start.next = self.tail
        self.tail.prev = self.start
    """ @param: key: An integer @param: value: An integer @return: nothing """
    def set(self, key, value):
        # write your code here
        node = self.maps.get(key)
        if node != None:
        	# 已存在key 更新visitcount 移动位置
            node.value = value
            node.visit_count += 1
            tmp = node.prev
            while node.visit_count >= tmp.visit_count and tmp != self.start:
                tmp = tmp.prev
            node.next.prev = node.prev
            node.prev.next = node.next
            node.next = tmp.next
            tmp.next.prev = node
            tmp.next = node
            node.prev = tmp
            return
            
        else:
        # key不存在 新建一个key 
        # 进一步分为两种情况 缓存已满和缓存未满
            node = self.ListNode(key, value, self.tail, self.tail.prev)
            self.tail.prev.next = node
            self.tail.prev = node
            if self.l < self.capacity:
                self.l += 1
            else:
                invalid_node = node.prev
                invalid_key = invalid_node.key
                del self.maps[invalid_key]
                invalid_node.prev.next = node
                node.prev = invalid_node.prev
            tmp = node.prev
            while node.visit_count >= tmp.visit_count and tmp != self.start:
                tmp = tmp.prev
            node.next.prev = node.prev
            node.prev.next = node.next
            node.next = tmp.next
            tmp.next.prev = node
            tmp.next = node
            node.prev = tmp
            
            self.maps[key] = node
            
    """ @param: key: An integer @return: An integer """
    def get(self, key):
        # write your code here
        node = self.maps.get(key)
        if node:
            node.visit_count += 1
            tmp = node.prev
            while node.visit_count >= tmp.visit_count and tmp != self.start:
                tmp = tmp.prev
            node.next.prev = node.prev
            node.prev.next = node.next
            node.next = tmp.next
            tmp.next.prev = node
            tmp.next = node
            node.prev = tmp
            return node.value
        else:
            return -1

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/10792.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信