牛客经典101题解题集--贪心算法+模拟

目录

贪心算法

分糖果问题

题目

代码

java

python

主持人调度(二)

题目

分析

代码

java

python

模拟

旋转数组

题目

代码

java

python

螺旋矩阵

题目

代码

java

python

顺时针旋转矩阵

题目

分析

代码

java

python

设计LRU缓存结构

题目

分析

代码

java

python

设计LFU缓存结构

题目

代码

java

python


贪心算法

分糖果问题

题目

一群孩子做游戏,现在请你根据游戏得分来发糖果,要求如下:

  1. 每个孩子不管得分多少,起码分到一个糖果。

  2. 任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果。(若相同则无此限制)

给定一个数组 𝑎𝑟𝑟arr 代表得分数组,请返回最少需要多少糖果。

要求: 时间复杂度为 𝑂(𝑛) 空间复杂度为 𝑂(𝑛)

数据范围: 1≤𝑛≤100000 ,1≤𝑎𝑖≤1000

示例1

输入:[1,1,2]

返回值:4

说明:最优分配方案为1,1,2

示例2

输入:[1,1,1]

返回值:3

说明:最优分配方案是1,1,1

代码

java
java 复制代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param S string字符串 
# @param T string字符串 
# @return string字符串
#
import collections
class Solution:
    def minWindow(self , S: str, T: str) -> str:
        # write code here
        if(len(T)>len(S)):
            return ""
        need=len(T)
        cnt = collections.Counter(T)
        start=0
        end=-1
        left=0
        right=0
        minl=len(S)+1
        while right<len(S):
            ch=S[right]
            if ch in cnt:
                if cnt[ch]>0:
                    need-=1
                cnt[ch]-=1
            while need==0:
                if right-left+1<minl:
                    minl=right-left+1
                    start=left
                    end=right
                ch1=S[left]
                if ch1 in cnt:
                    if cnt[ch1] >= 0:    # 对当前字符ch还有需求,或刚好无需求(其实此时只有=0的情况)
                        need += 1       # 此时滑出窗口的ch会对need有影响
                    cnt[ch1] += 1
                left += 1  
            right+=1      
        return S[start:end+1]
python
python 复制代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# pick candy
# @param arr int整型一维数组 the array
# @return int整型
#
class Solution:
    def candy(self , arr: List[int]) -> int:
        # write code here
        candy=[1]*len(arr)
        result=0
        for i in range(1,len(arr)):
            if arr[i]>arr[i-1]:
                candy[i]=candy[i-1]+1
        for j in range(len(arr)-2,-1,-1):
            if arr[j]>arr[j+1]:
                candy[j]=max(candy[j],candy[j+1]+1)
        for c in candy:
            result+=c
        return result

主持人调度(二)

题目

有 n 个活动即将举办,每个活动都有开始时间与活动的结束时间,第 i 个活动的开始时间是 starti ,第 i 个活动的结束时间是 endi ,举办某个活动就需要为该活动准备一个活动主持人。

一位活动主持人在同一时间只能参与一个活动。并且活动主持人需要全程参与活动,换句话说,一个主持人参与了第 i 个活动,那么该主持人在 (starti,endi) 这个时间段不能参与其他任何活动。求为了成功举办这 n 个活动,最少需要多少名主持人。

数据范围: 1≤𝑛≤105, −232≤𝑠𝑡𝑎𝑟𝑡𝑖≤𝑒𝑛𝑑𝑖≤231−1

复杂度要求:时间复杂度 𝑂(𝑛log⁡𝑛),空间复杂度 𝑂(𝑛)

示例1

输入:2,[[1,2],[2,3]]

返回值:1

说明:只需要一个主持人就能成功举办这两个活动

示例2

输入:2,[[1,3],[2,4]]

返回值:2

说明:需要两个主持人才能成功举办这两个活动

备注:1≤𝑛≤1051≤n≤105

𝑠𝑡𝑎𝑟𝑡𝑖,𝑒𝑛𝑑𝑖starti​,endi​在int范围内

分析

如果当前活动开始时,最早空闲的主持人已经闲了 那么复用他,不然新增加一个主持人

代码

java
java 复制代码
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 计算成功举办活动需要多少名主持人
     * @param n int整型 有n个活动
     * @param startEnd int整型二维数组 startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间
     * @return int整型
     */
    public int minmumNumberOfHost (int n, int[][] startEnd) {
        // write code here
        Arrays.sort(startEnd,(a,b) ->Integer.compare(a[0],b[0]));
        int[] end=new int[n];
        for(int i=0;i<n;i++){
            end[i]=startEnd[i][1];
        }
        Arrays.sort(end);
        int count=0;
        int endIdx=0;
        for(int i=0;i<n;i++){
            int s = startEnd[i][0];
            if (s >= end[endIdx]) {
                endIdx++; // 复用主持人
            }else{
                count++;
            }
        }
        return count;
    }
}
python
python 复制代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 计算成功举办活动需要多少名主持人
# @param n int整型 有n个活动
# @param startEnd int整型二维数组 startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间
# @return int整型
#
class Solution:
    def minmumNumberOfHost(self , n: int, startEnd: List[List[int]]) -> int:
        # write code here
        start = []
        end = []
    
        for s, e in startEnd:
            start.append(s)
            end.append(e)
    
    # 分别排序!这是最关键的一步
        start.sort()
        end.sort()
    
        count = 0       # 需要的主持人数
        end_idx = 0     # 指向最早空闲的主持人
    
        for s in start:
        # 如果当前活动开始时,最早的主持人已经闲了
            if s >= end[end_idx]:
                end_idx += 1    # 复用这个主持人
            else:
                count += 1      # 不够,加人
    
        return count

模拟

旋转数组

题目

一个数组A中存有 n 个整数,在不允许使用另外数组的前提下,将每个整数循环向右移 M( M >=0)个位置,即将A中的数据由(A0 A1 ......AN-1 )变换为(AN-M ...... AN-1 A0 A1 ......AN-M-1 )(最后 M 个数循环移至最前面的 M 个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

数据范围:0<𝑛≤100,0≤𝑚≤1000

进阶:空间复杂度 𝑂(1),时间复杂度 𝑂(𝑛)

示例1

输入:6,2,[1,2,3,4,5,6]

返回值:[5,6,1,2,3,4]

示例2

输入:4,0,[1,2,3,4]

返回值:[1,2,3,4]

备注:(1<=N<=100,M>=0)

代码

java
java 复制代码
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 旋转数组
     * @param n int整型 数组长度
     * @param m int整型 右移距离
     * @param a int整型一维数组 给定数组
     * @return int整型一维数组
     */
    public int[] solve (int n, int m, int[] a) {
        // write code here
        m = m % n;
        reverse(a,0,n-1);
        reverse(a,0,m-1);
        reverse(a,m,n-1);
        return a;
    }
    public void reverse(int[] a,int start,int end){
        while(start<=end){
            int temp=a[start];
            a[start]=a[end];
            a[end]=temp;
            start++;
            end--;
        }
    }
}
python
python 复制代码
from re import A
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 旋转数组
# @param n int整型 数组长度
# @param m int整型 右移距离
# @param a int整型一维数组 给定数组
# @return int整型一维数组
#
class Solution:
    def solve(self , n: int, m: int, a: List[int]) -> List[int]:
        # write code here
        m%=len(a)
        self.reverse(a,0,len(a)-1)
        self.reverse(a,0,m-1)
        self.reverse(a,m,len(a)-1)
        return a

    def reverse(self,nums:List[int],start:int,end:int) ->None:
        while start<=end:
            temp=nums[start]
            nums[start]=nums[end]
            nums[end]=temp
            start+=1
            end-=1

螺旋矩阵

题目

给定一个m x n大小的矩阵(m行,n列),按螺旋的顺序返回矩阵中的所有元素。

数据范围:0≤𝑛,𝑚≤10,矩阵中任意元素都满足 ∣𝑣𝑎𝑙∣≤100

要求:空间复杂度 𝑂(𝑛𝑚),时间复杂度 𝑂(𝑛𝑚)

示例1

输入:[[1,2,3],[4,5,6],[7,8,9]]

返回值:[1,2,3,6,9,8,7,4,5]

示例2

输入:[]

返回值:[]

代码

java
java 复制代码
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param matrix int整型二维数组
     * @return int整型ArrayList
     */
    public ArrayList<Integer> spiralOrder (int[][] matrix) {
        // write code here
        ArrayList<Integer> res= new ArrayList<>();
        if (matrix == null || matrix.length <= 0 || matrix[0].length <= 0) {
            return res;
        }
        int left = 0, right = matrix[0].length - 1, top = 0, bottom = matrix.length - 1;
            
        
        while (true) {
            for (int i = left; i <= right; i++) {
                res.add(matrix[top][i])  ;
                
            }
            if (++top > bottom) break;
            for (int j = top; j <= bottom; j++) {
                res.add(matrix[j][right])  ;
                
            }
            if (left > --right) break;
            for (int i = right; i >= left; i--) {
                res.add(matrix[bottom][i]);

            }
            if (top > --bottom) break;
            for (int j = bottom; j >= top; j--) {
                res.add(matrix[j][left]) ;
                
            }
            if (++left > right) {
                break;
            }
        }
        return res;
    }
}
python
python 复制代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param matrix int整型二维数组 
# @return int整型一维数组
#
class Solution:
    def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
        # write code here
        list=[]
        if len(matrix)==0 or len(matrix[0])==0:
            return list
        m=len(matrix)
        n=len(matrix[0])
        left=0
        right=n-1
        top=0
        bottom=m-1
        while(1):
            for i in range(left,right+1):
                list.append(matrix[top][i])
            top+=1
            if top>bottom:
                break
            for j in range(top,bottom+1):
                list.append(matrix[j][right])
            right-=1
            if left>right:
                break
            for i in range(right,left-1,-1):
                list.append(matrix[bottom][i])
            bottom-=1
            if top>bottom:
                break
            for j in range(bottom,top-1,-1):
                list.append(matrix[j][left])
            left+=1
            if left>right:
                break
            
        return list
                
                
            

顺时针旋转矩阵

题目

有一个NxN整数矩阵,请编写一个算法,将矩阵顺时针旋转90度。

给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵。

数据范围:0<𝑛<300,矩阵中的值满足 0≤𝑣𝑎𝑙≤1000

要求:空间复杂度 𝑂(𝑁2),时间复杂度 𝑂(𝑁2)

进阶:空间复杂度 𝑂(1),时间复杂度 𝑂(𝑁2)

示例1

输入:[[1,2,3],[4,5,6],[7,8,9]],3

返回值:[[7,4,1],[8,5,2],[9,6,3]]

分析

矩阵转置:沿着主对角线(左上→右下)交换元素

每行反转:将每一行的元素左右对称反转

代码

java
java 复制代码
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param mat int整型二维数组 
     * @param n int整型 
     * @return int整型二维数组
     */
    public int[][] rotateMatrix (int[][] mat, int n) {
        // write code here
        for(int i=0;i<n;i++){
            for(int j=0;j<i;j++){
                int temp=mat[i][j];
                mat[i][j]=mat[j][i];
                mat[j][i]=temp;
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n/2;j++){
                int temp=mat[i][j];
                mat[i][j]=mat[i][n-1-j];
                mat[i][n-1-j]=temp;
            }
        }
        return mat;
    }
}
python
python 复制代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param mat int整型二维数组 
# @param n int整型 
# @return int整型二维数组
#
class Solution:
    def rotateMatrix(self , mat: List[List[int]], n: int) -> List[List[int]]:
        # write code here
        for i in range(n):
            for j in range(i):
                mat[i][j],mat[j][i]=mat[j][i],mat[i][j]
        for i in range(n):
            for j in range(n//2):
                mat[i][j],mat[i][n-1-j]=mat[i][n-1-j],mat[i][j]
        return mat

设计LRU缓存结构

题目

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

  1. Solution(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存

  2. get(key):如果关键字 key 存在于缓存中,则返回key对应的value值,否则返回 -1 。

  3. set(key, value):将记录(key, value)插入该结构,如果关键字 key 已经存在,则变更其数据值 value,如果不存在,则向缓存中插入该组 key-value ,如果key-value的数量超过capacity,弹出最久未使用的key-value

提示:

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

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

3.返回的value都以字符串形式表达,如果是set,则会输出"null"来表示(不需要用户返回,系统会自动输出),方便观察

4.函数set和get必须以O(1)的方式运行

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

数据范围:

1≤𝑐𝑎𝑝𝑎𝑐𝑖𝑡𝑦<=1051

0≤𝑘𝑒𝑦,𝑣𝑎𝑙≤2×109

1≤𝑛≤105

示例1

输入:["set","set","get","set","get","set","get","get","get"],[[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]],2

返回值:["null","null","1","null","-1","null","-1","3","4"]

说明:我们将缓存看成一个队列,最后一个参数为2代表capacity,所以 Solution s = new Solution(2); s.set(1,1); //将(1,1)插入缓存,缓存是{"1"=1},set操作返回"null" s.set(2,2); //将(2,2)插入缓存,缓存是{"2"=2,"1"=1},set操作返回"null" output=s.get(1);// 因为get(1)操作,缓存更新,缓存是{"1"=1,"2"=2},get操作返回"1" s.set(3,3); //将(3,3)插入缓存,缓存容量是2,故去掉某尾的key-value,缓存是{"3"=3,"1"=1},set操作返回"null" output=s.get(2);// 因为get(2)操作,不存在对应的key,故get操作返回"-1" s.set(4,4); //将(4,4)插入缓存,缓存容量是2,故去掉某尾的key-value,缓存是{"4"=4,"3"=3},set操作返回"null" output=s.get(1);// 因为get(1)操作,不存在对应的key,故get操作返回"-1" output=s.get(3);//因为get(3)操作,缓存更新,缓存是{"3"=3,"4"=4},get操作返回"3" output=s.get(4);//因为get(4)操作,缓存更新,缓存是{"4"=4,"3"=3},get操作返回"4"

分析

也就是最近最少使用。要记录使用次数,map来

代码

java
java 复制代码
import java.util.*;


public class Solution {
    private static class Node {
        int key, value;
        Node prev, next;

        Node(int k, int v) {
            key = k;
            value = v;
        }
    }

    private final int capacity;
    private final Node dummy = new Node(0, 0); // 哨兵节点
    private final Map<Integer, Node> keyToNode = new HashMap<>();

    public Solution(int capacity) {
// write code here/
        this.capacity = capacity;
        dummy.prev = dummy;
        dummy.next = dummy;
    }
    public int get(int key) {
        // write code here
        Node node = getNode(key);
        return node != null ? node.value : -1;
    }

    public void set(int key, int value) {
// write code here
        Node node = getNode(key);
        if (node != null) { // 有这本书
            node.value = value; // 更新 value
            return;
        }
        node = new Node(key, value); // 新书
        keyToNode.put(key, node);
        pushFront(node); // 放在最上面
        if (keyToNode.size() > capacity) { // 书太多了
            Node backNode = dummy.prev;
            keyToNode.remove(backNode.key);
            remove(backNode); // 去掉最后一本书
        }

    }
    private Node getNode(int key) {
        if (!keyToNode.containsKey(key)) { // 没有这本书
            return null;
        }
        Node node = keyToNode.get(key); // 有这本书
        remove(node); // 把这本书抽出来
        pushFront(node); // 放在最上面
        return node;
    }

    // 删除一个节点(抽出一本书)
    private void remove(Node x) {
        x.prev.next = x.next;
        x.next.prev = x.prev;
    }

    // 在链表头添加一个节点(把一本书放在最上面)
    private void pushFront(Node x) {
        x.prev = dummy;
        x.next = dummy.next;
        x.prev.next = x;
        x.next.prev = x;
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution solution = new Solution(capacity);
 * int output = solution.get(key);
 * solution.set(key,value);
 */
python
python 复制代码
class Node:
    def __init__(self, key=0, value=0):
        self.key = key
        self.value = value
        self.prev = None
        self.next = None

class Solution:
    def __init__(self, capacity: int):
        self.capacity = capacity
        self.key_to_node = dict()
        
        # 哨兵节点(双向链表)
        self.dummy = Node()
        self.dummy.prev = self.dummy
        self.dummy.next = self.dummy
    
    def get(self, key: int) -> int:
        node = self.get_node(key)
        return node.value if node else -1
    
    def set(self, key: int, value: int) -> None:
        node = self.get_node(key)
        if node:
            node.value = value
            return
        
        # 新增节点
        node = Node(key, value)
        self.key_to_node[key] = node
        self.push_front(node)
        
        # 超过容量,删除最后一个
        if len(self.key_to_node) > self.capacity:
            back_node = self.dummy.prev
            del self.key_to_node[back_node.key]
            self.remove(back_node)
    
    def get_node(self, key):
        if key not in self.key_to_node:
            return None
        node = self.key_to_node[key]
        self.remove(node)
        self.push_front(node)
        return node
    
    # 删除节点
    def remove(self, x):
        x.prev.next = x.next
        x.next.prev = x.prev
    
    # 插入到链表头部
    def push_front(self, x):
        x.prev = self.dummy
        x.next = self.dummy.next
        x.prev.next = x
        x.next.prev = x

设计LFU缓存结构

题目

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

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

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

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

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

数据范围:0<𝑘≤105,∣𝑣𝑎𝑙∣≤2×109

要求:get和set的时间复杂度都是 𝑂(𝑙𝑜𝑔𝑛),空间复杂度是 𝑂(𝑛)

若opt=1,接下来两个整数x, y,表示set(x, y)

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

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

示例1

输入:[[1,1,1],[1,2,2],[1,3,2],[1,2,4],[1,3,5],[2,2],[1,4,4],[2,1]],3

返回值:[4,-1]

说明:在执行"1 4 4"后,"1 1 1"被删除。因此第二次询问的答案为-1

备注:1≤𝑘≤𝑛≤1051≤k≤n≤105 −2×109≤𝑥,𝑦≤2×109−2×109≤x,y≤2×109

代码

java
java 复制代码
import java.util.*;

public class Solution {
    /**
     * lfu design
     * @param operators int整型二维数组 ops
     * @param k int整型 the k
     * @return int整型一维数组
     */
    public int[] LFU (int[][] operators, int k) {
        LFUCache lfu = new LFUCache(k);
        List<Integer> res = new ArrayList<>();
        
        for (int[] op : operators) {
            if (op[0] == 1) { // set 操作
                int key = op[1];
                int val = op[2];
                lfu.put(key, val);
            } else if (op[0] == 2) { // get 操作
                int key = op[1];
                res.add(lfu.get(key));
            }
        }
        
        // 转成 int[] 返回
        int[] ans = new int[res.size()];
        for (int i = 0; i < res.size(); i++) {
            ans[i] = res.get(i);
        }
        return ans;
    }
}

// 下面直接放你给的 LFUCache 完整代码
class LFUCache {
    private static class Node {
        int key, value, freq = 1;
        Node prev, next;

        Node(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }

    private final int capacity;
    private final Map<Integer, Node> keyToNode = new HashMap<>();
    private final Map<Integer, Node> freqToDummy = new HashMap<>();
    private int minFreq;

    public LFUCache(int capacity) {
        this.capacity = capacity;
    }

    public int get(int key) {
        Node node = getNode(key);
        return node != null ? node.value : -1;
    }

    public void put(int key, int value) {
        Node node = getNode(key);
        if (node != null) {
            node.value = value;
            return;
        }
        if (keyToNode.size() == capacity) {
            Node dummy = freqToDummy.get(minFreq);
            Node backNode = dummy.prev;
            keyToNode.remove(backNode.key);
            remove(backNode);
            if (dummy.prev == dummy) {
                freqToDummy.remove(minFreq);
            }
        }
        node = new Node(key, value);
        keyToNode.put(key, node);
        pushFront(1, node);
        minFreq = 1;
    }

    private Node getNode(int key) {
        if (!keyToNode.containsKey(key)) {
            return null;
        }
        Node node = keyToNode.get(key);
        remove(node);
        Node dummy = freqToDummy.get(node.freq);
        if (dummy.prev == dummy) {
            freqToDummy.remove(node.freq);
            if (minFreq == node.freq) {
                minFreq++;
            }
        }
        node.freq++;
        pushFront(node.freq, node);
        return node;
    }

    private Node newList() {
        Node dummy = new Node(0, 0);
        dummy.prev = dummy;
        dummy.next = dummy;
        return dummy;
    }

    private void pushFront(int freq, Node x) {
        Node dummy = freqToDummy.computeIfAbsent(freq, k -> newList());
        x.prev = dummy;
        x.next = dummy.next;
        x.prev.next = x;
        x.next.prev = x;
    }

    private void remove(Node x) {
        x.prev.next = x.next;
        x.next.prev = x.prev;
    }
}
python
python 复制代码
class Node:
    def __init__(self, key=0, val=0):
        self.key = key
        self.val = val
        self.freq = 1
        self.prev = None
        self.next = None

class Solution:
    def LFU(self, operators: List[List[int]], k: int) -> List[int]:
        res = []
        
        # 内部LFU结构
        class LFUCache:
            def __init__(self, capacity):
                self.capacity = capacity
                self.key_to_node = dict()
                self.freq_to_dummy = dict()
                self.min_freq = 1

            def get(self, key):
                if key not in self.key_to_node:
                    return -1
                node = self.key_to_node[key]
                self._update(node)
                return node.val

            def put(self, key, val):
                if self.capacity == 0:
                    return
                if key in self.key_to_node:
                    node = self.key_to_node[key]
                    node.val = val
                    self._update(node)
                    return
                
                if len(self.key_to_node) >= self.capacity:
                    dummy = self.freq_to_dummy[self.min_freq]
                    remove_node = dummy.prev
                    self._remove(remove_node)
                    del self.key_to_node[remove_node.key]
                    
                    if dummy.prev == dummy:
                        del self.freq_to_dummy[self.min_freq]

                new_node = Node(key, val)
                self.key_to_node[key] = new_node
                self._add(new_node, 1)
                self.min_freq = 1

            def _update(self, node):
                old_freq = node.freq
                self._remove(node)
                
                dummy = self.freq_to_dummy[old_freq]
                if dummy.prev == dummy:
                    del self.freq_to_dummy[old_freq]
                    if self.min_freq == old_freq:
                        self.min_freq += 1

                node.freq += 1
                self._add(node, node.freq)

            def _add(self, node, freq):
                if freq not in self.freq_to_dummy:
                    dummy = Node()
                    dummy.prev = dummy
                    dummy.next = dummy
                    self.freq_to_dummy[freq] = dummy
                else:
                    dummy = self.freq_to_dummy[freq]

                node.prev = dummy
                node.next = dummy.next
                dummy.next.prev = node
                dummy.next = node

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

        cache = LFUCache(k)
        for op in operators:
            if op[0] == 1:
                # set 操作
                cache.put(op[1], op[2])
            else:
                # get 操作
                res.append(cache.get(op[1]))
        return res
相关推荐
AKDreamer_HeXY1 小时前
QOJ 12255 - 36 Puzzle 题解
数据结构·c++·数学·算法·icpc·qoj
AI进化营-智能译站1 小时前
ROS2 C++开发系列13-运算符重载让ROS2消息处理更自然
java·开发语言·c++·ai
AI科技星1 小时前
《全域数学》第一部 数术本源 第三卷 代数原本第14篇 附录二 猜想证明【乖乖数学】
人工智能·算法·数学建模·数据挖掘·量子计算
shjita2 小时前
java根据键值对中值的大小进行排序的手法。
java·开发语言·servlet
Wect2 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·typescript
憨波个2 小时前
【说话人日志】DOVER-Lap:overlap-aware diarization 输出融合算法
人工智能·深度学习·算法·音频·语音识别
叼烟扛炮2 小时前
C++第四讲:类和对象(下)
c++·算法·类和对象
Rabitebla2 小时前
vector 的骨架:三根指针、模板陷阱与迭代器失效的第一现场
开发语言·数据结构·c++·算法
薪火铺子2 小时前
Spring Security 6.x 实战指南
java·后端·spring