首页 > 试题广场 >

设计LFU缓存结构

[编程题]设计LFU缓存结构
  • 热度指数:23499 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
一个缓存结构需要实现如下功能。
  • set(key, value):将记录(key, value)插入该结构
  • get(key):返回key对应的value值
但是缓存结构中最多放K条记录,如果新的第K+1条记录要加入,就需要根据策略删掉一条记录,然后才能把新记录加入。这个策略为:在缓存结构的K条记录中,哪一个key从进入缓存结构的时刻开始,被调用set或者get的次数最少,就删掉这个key的记录;
如果调用次数最少的key有多个,上次调用发生最早的key被删除
这就是LFU缓存替换算法。实现这个结构,K作为参数给出

数据范围:
要求: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   

备注:

通过
#include <stdio.h>
#include <string.h>
struct ListTable{
    int key;
    int value;
    struct ListTable *last;
    struct ListTable *next;
    int count;
};
typedef struct List{
    int  capacity;
    int  NodeNum;
    //struct ListTable *HashTable[2000000001];
    struct ListTable *head,*end;
} Solution;

struct ListTable* searchMinCountNode(Solution* obj) {
    struct ListTable* p;
    int Min=100001;
    p = obj->head;
    while(p!=NULL) {
        if(Min > p->count)
            Min = p->count;
        p = p->next;
    }
    p = obj->head;
    while(p->next!=NULL) {
        if(Min == p->count)
            return p;
        p = p->next;
    }
    return obj->head;
}

struct ListTable* searchNode(Solution* obj, int key) {
    struct ListTable* p = obj->head;
    while(p!=NULL) {
        if(p->key == key)
            return p;
        p = p->next;
    }
    return NULL;
}

void SubNode(Solution* obj, int key, struct ListTable* HashTable) {
    if(HashTable==obj->head){
        obj->head = obj->head->next;
        obj->head->last = NULL;
    }
    else  if(HashTable==obj->end) {
        obj->end = HashTable->last;
        obj->end->next = NULL;
    }
    else {
        HashTable->last->next = HashTable->next;
        HashTable->next->last = HashTable->last;
    }
    HashTable->next = NULL;
    HashTable->last = NULL;
}

void AddEndNode(Solution* obj, int key, int value, struct ListTable* HashTable) {
    obj->end->next = HashTable;
    HashTable->last = obj->end;
    HashTable->next = NULL;
    obj->end = HashTable;
    HashTable->key = key;
    HashTable->value = value;
}

Solution* SolutionCreate(int capacity) {
    int i;
    Solution *res;
    res = (Solution*)malloc(sizeof(Solution));
    res->capacity = capacity;
    res->NodeNum = 0;
    res->head = NULL;
    res->end = NULL;
    return res;
}

int SolutionGet(Solution* obj, int key) {
    struct ListTable* HashTable = searchNode(obj, key);
    if(HashTable == NULL) 
        return -1;
    if(HashTable!=obj->end) {
        SubNode(obj, key, HashTable);
        AddEndNode(obj, key, HashTable->value, HashTable);
    }
    HashTable->count++;
    return HashTable->value; 
}

void SolutionPut(Solution* obj, int key, int value) {
    struct ListTable* HashTable = searchNode(obj, key);
    if(obj->head == NULL) {
        obj->head = (struct ListTable*)malloc(sizeof(struct ListTable));
        obj->end = obj->head;
        obj->head->key = key;
        obj->head->value = value;
        obj->head->last = NULL;
        obj->head->next = NULL;
        obj->head->count = 1;
        obj->NodeNum = 1;
    }
    else {
        if(HashTable == NULL) {
            struct ListTable* NewNode;
            NewNode = (struct ListTable*)malloc(sizeof(struct ListTable));
            obj->NodeNum++;
            NewNode->count = 1;
            AddEndNode(obj, key, value, NewNode);
        }   
        else {
            if(HashTable == obj->end){
                HashTable->value = value;
                HashTable->count++;
            }
            else {
                SubNode(obj, key, HashTable);
                AddEndNode(obj, key, value, HashTable);
                HashTable->count++;
            }
        }
            
        if(obj->NodeNum > obj->capacity) {
            struct ListTable* p = obj->head;
            p = searchMinCountNode(obj);
            SubNode(obj, p->key, p);
            free(p);
            obj->NodeNum--;
        }
    }
}

void SolutionFree(Solution* obj) {
    int i;
    struct ListTable* p = obj->head;
    for(i=0; i<obj->NodeNum-1; i++) {
        struct ListTable* last=p;
        p = p->next;
        free(last);
    }
    free(obj);
}

int* LFU(int** operators, int operatorsRowLen, int* operatorsColLen, int k, int* returnSize ) {
    Solution *obj = SolutionCreate(k);
    int i, *res;
    res = (int*)malloc(100000*sizeof(int));
    (*returnSize) = 0;
    for(i=0; i<operatorsRowLen; i++) {
        if(operators[i][0]==1) 
            SolutionPut(obj, operators[i][1], operators[i][2]);
        else 
            res[(*returnSize)++] = SolutionGet(obj, operators[i][1]);
    }
    SolutionFree(obj);
    return res;
}

编辑于 2024-03-29 22:06:12 回复(0)

问题信息

难度:
2条回答 3723浏览

热门推荐

通过挑战的用户

查看代码