leetcode做题笔记146. LRU 缓存

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。

实现 LRUCache 类:

  • LRUCache(int capacity)正整数 作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1
  • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

函数 getput 必须以 O(1) 的平均时间复杂度运行。

思路一:双向链表

c语言解法

cpp 复制代码
struct LRUInfo{
    int val;
    int value;
    struct LRUInfo* pre;
    struct LRUInfo* next;
};

typedef struct {
    int top;
    int total;
    struct LRUInfo * head;
    struct LRUInfo * rear;
    struct LRUInfo lruinfo[10001];
} LRUCache;

LRUCache* lRUCacheCreate(int capacity) {
    LRUCache* obj = calloc(1, sizeof(LRUCache));
    obj->total = capacity;
    obj->head = calloc(1, sizeof(struct LRUInfo));
    obj->rear = calloc(1, sizeof(struct LRUInfo));
    obj->head->next = obj->rear;
    obj->rear->pre = obj->head;
    return obj;
}

int lRUCacheGet(LRUCache* obj, int key) {
    if (obj->lruinfo[key].val == 1) {
        obj->lruinfo[key].pre->next = obj->lruinfo[key].next;
        obj->lruinfo[key].next->pre = obj->lruinfo[key].pre;
        obj->rear->pre->next = obj->lruinfo + key;
        obj->lruinfo[key].pre = obj->rear->pre;
        obj->lruinfo[key].next = obj->rear;
        obj->rear->pre = obj->lruinfo + key;
        return obj->lruinfo[key].value;
    }
    return -1;
}

void lRUCachePut(LRUCache* obj, int key, int value) {
    if (obj->lruinfo[key].val == 0 && obj->top < obj->total) {
        (obj->top)++;
        obj->rear->pre->next = obj->lruinfo + key;
        obj->lruinfo[key].pre = obj->rear->pre;
        obj->lruinfo[key].next = obj->rear;
        obj->lruinfo[key].val = 1;
        obj->lruinfo[key].value = value;
        obj->rear->pre = obj->lruinfo + key;
    } else if (obj->lruinfo[key].val == 1){
        obj->lruinfo[key].pre->next = obj->lruinfo[key].next;
        obj->lruinfo[key].next->pre = obj->lruinfo[key].pre;
        obj->rear->pre->next = obj->lruinfo + key;
        obj->lruinfo[key].pre = obj->rear->pre;
        obj->lruinfo[key].next = obj->rear;
        obj->lruinfo[key].value = value;
        obj->rear->pre = obj->lruinfo + key;
    } else if (obj->lruinfo[key].val == 0 && obj->top >= obj->total && obj->head->next != NULL) {
        obj->lruinfo[key].val = 1;
        obj->lruinfo[key].value = value;
        obj->rear->pre->next = obj->lruinfo + key;
        obj->lruinfo[key].pre = obj->rear->pre;
        obj->lruinfo[key].next = obj->rear;
        obj->rear->pre = obj->lruinfo + key;
        obj->head->next->val = 0;
        obj->head->next = obj->head->next->next;
        obj->head->next->pre = obj->head;       
    }
    return;
}

void lRUCacheFree(LRUCache* obj) {
    free(obj);
}

/**
 * Your LRUCache struct will be instantiated and called as such:
 * LRUCache* obj = lRUCacheCreate(capacity);
 * int param_1 = lRUCacheGet(obj, key);
 
 * lRUCachePut(obj, key, value);
 
 * lRUCacheFree(obj);
*/

分析:

本题要实现LRU缓存实现双向链表的各个操作后即可解决,删除方法利用前驱节点的指针才能满足O(1)的时间复杂度,get方法利用前驱节点达到O(1)的时间复杂度

总结:

本题考察对LRU缓存的实现,考虑到各个方法的实现的时间复杂度要求在O(1),所以采用双向链表保证时间复杂度,最后实现各个方法即可解决

相关推荐
仙俊红15 小时前
LeetCode每日一题,20250914
算法·leetcode·职场和发展
Hello_Embed19 小时前
STM32HAL 快速入门(二十):UART 中断改进 —— 环形缓冲区解决数据丢失
笔记·stm32·单片机·学习·嵌入式软件
咸甜适中19 小时前
rust语言 (1.88) 学习笔记:客户端和服务器端同在一个项目中
笔记·学习·rust
Grassto20 小时前
RAG 从入门到放弃?丐版 demo 实战笔记(go+python)
笔记
Magnetic_h20 小时前
【iOS】设计模式复习
笔记·学习·ios·设计模式·objective-c·cocoa
MarkHard12321 小时前
如何利用redis使用一个滑动窗口限流
数据库·redis·缓存
心想事成的幸运大王1 天前
Redis的过期策略
数据库·redis·缓存
周周记笔记1 天前
学习笔记:第一个Python程序
笔记·学习
丑小鸭是白天鹅1 天前
Kotlin协程详细笔记之切线程和挂起函数
开发语言·笔记·kotlin
潘达斯奈基~1 天前
《大数据之路1》笔记2:数据模型
大数据·笔记