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),所以采用双向链表保证时间复杂度,最后实现各个方法即可解决

相关推荐
Engineer邓祥浩11 分钟前
JVM学习笔记(10) 第三部分 虚拟机执行子系统 第9章 类加载及执行子系统的案例与实战
jvm·笔记·学习
juniperhan27 分钟前
Flink 系列第10篇:Flink 分布式缓存详解
分布式·缓存·flink
m0_7167652327 分钟前
数据结构--单链表的插入、删除、查找详解
c语言·开发语言·数据结构·c++·笔记·学习·visual studio
SPC的存折33 分钟前
自用LNMP-Redis-NFS-Discuz5.0部署指南-脚本版
linux·运维·服务器·数据库·redis·mysql·缓存
_李小白41 分钟前
【OSG学习笔记】Day 53: Text3D( 三维文字)
笔记·学习·3d
圣保罗的大教堂1 小时前
leetcode 874. 模拟行走机器人 中等
leetcode
Oll Correct1 小时前
实验十七:验证路由器既隔离碰撞域也隔离广播域
网络·笔记
zhangrelay1 小时前
智能时代机器人工程师・云原生 + 大模型 + 智能体 全栈成长计划(2026 版)
笔记·学习
杰克尼2 小时前
redis(day05-分布式缓存)
数据库·redis·缓存
剑挑星河月2 小时前
394.字符串解码
数据结构·算法·leetcode