【Leetcode刷题】LFU缓存

题目:https://leetcode-cn.com/problems/lfu-cache/

思路:

O(1)的数据结构:hashmap

维持最近使用:OrderdDict(详见LRU缓存问题)

使用一个hashmap维系key到出现频率的映射关系

另一个hashmap维系频率到数据(key-value键值对)的关系

由于 当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最近 最少使用的键。因此key-value键值对应该用OrderdDict存储

import collections

class LFUCache:
    # self.key_fre是key到出现频率的映射关系
    # self.fre_data格式:
    # {
    #     fre1:{
    #         key1:value1,
    #         ...
    #     }
    #     ...
    # }
    def __init__(self, capacity: int):
        self.capacity = capacity
        self.count = 0

        self.key_fre = {}
        # 同一频率下,去除最近最少使用的健,退化为LRU缓存问题
        self.fre_data = {}
        self.min_fre = 1

    # 更新某一键值对的频率
    def update_fre(self, key, value=None):
        # 需要从self.fre_data中取值
        fre = self.key_fre[key]
        next_fre = fre + 1
        # 从原频率字典删除
        res = self.fre_data[fre].pop(key)
        # 如果当前频率是最小频率,且字典为空,则更新最小频次记录
        if fre == self.min_fre and not self.fre_data[fre]:
            self.min_fre = next_fre
        # 插入下一个频率字典
        if next_fre not in self.fre_data:
            self.fre_data[next_fre] = collections.OrderedDict()
        self.fre_data[next_fre][key] = value if value is not None else res
        # 修改原key与频率的对应关系
        self.key_fre[key] = next_fre
        return res

    def get(self, key: int) -> int:
        if key not in self.key_fre:
            return -1
        return self.update_fre(key)

    def put(self, key: int, value: int) -> None:
        # capacity还能是0
        if self.capacity == 0:
            return
        # 如果是更新,则要变更key所处频率字典
        if key in self.key_fre:
            self.update_fre(key, value)
        else:
            if self.count >= self.capacity:
                # 缓存已满,从最小频次字典中pop最少使用的
                item = self.fre_data[self.min_fre].popitem(last=False)
                # 删掉对应key与频率的映射关系
                del self.key_fre[item[0]]
            else:
                self.count += 1
            # 新加入,更新最小频率
            self.min_fre = 1
            self.key_fre[key] = 1
            if 1 not in self.fre_data:
                self.fre_data[1] = collections.OrderedDict()
            self.fre_data[1][key] = value

原文地址:https://www.cnblogs.com/luozx207/p/12696107.html

时间: 2024-10-15 01:35:56

【Leetcode刷题】LFU缓存的相关文章

【leetcode刷题笔记】Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / 2 3 T

leetcode 刷题之路 63 Binary Tree Zigzag Level Order Traversal

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 return its zig

leetcode 刷题之路 64 Construct Binary Tree from Inorder and Postorder Traversal

Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. 给出二叉树的中序遍历和后序遍历结果,恢复出二叉树. 后序遍历序列的最后一个元素值是二叉树的根节点的值,查找该元素在中序遍历序列中的位置mid,根据中序遍历和后序遍历性质,有: 位置mid以前的序列部分为二叉树根节点左子树中

【leetcode刷题笔记】Longest Consecutive Sequence

Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example,Given [100, 4, 200, 1, 3, 2],The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. Your algorithm should run in

【leetcode刷题笔记】Remove Duplicates from Sorted Array II

Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For example,Given sorted array A = [1,1,1,2,2,3], Your function should return length = 5, and A is now [1,1,2,2,3]. 题解: 设置两个变量:右边kepler和前向游标forward.如果当前kepeler所指的元素和

【leetcode刷题笔记】Restore IP Addresses

Given a string containing only digits, restore it by returning all possible valid IP address combinations. For example:Given "25525511135", return ["255.255.11.135", "255.255.111.35"]. (Order does not matter) 题解:深度优先搜索.用resul

【leetcode刷题笔记】Path Sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. For example:Given the below binary tree and sum = 22, 5 / 4 8 / / 11 13 4 / \ 7 2 1 return true, as t

【leetcode刷题笔记】Insertion Sort List

Sort a linked list using insertion sort. 题解:实现链表的插入排序. 要注意的地方就是,处理链表插入的时候尽量往当前游标的后面插入,而不要往前面插入,后者非常麻烦.所以每次利用kepeler.next.val和head.val比较大小,而不是kepeler.val和head.val比较大小,因为如果用后者,要把head指向的节点插入到kepeler指向的节点的前面,如果kepeler指向的节点是头结点,就更麻烦了. 代码如下: 1 /** 2 * Defi

【leetcode刷题笔记】Max Points on a Line

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. 题解: 思路比较简单,每条直线都可以表示为y=kx+b,所以对于任意三点,如果它们共线,那么它们中任意两点的斜率都相等. 所以就遍历points数组,对其中的每一个元素计算它和位于它后面的数组元素的斜率并保存在一个hashmap中. 这个hashmap的键就是两点构成直线的斜率,值就是和当前元素po

【leetcode刷题笔记】Spiral Matrix II

Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For example,Given n = 3, You should return the following matrix: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 题解:以前做过的Spiral Matrix是给一个矩阵螺旋式的输出,这道题是给一个n,螺旋式的