• 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 ,则应该 逐出 最久未使用的关键字。

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

    思路一:双向链表

    c语言解法

    1. struct LRUInfo{
    2. int val;
    3. int value;
    4. struct LRUInfo* pre;
    5. struct LRUInfo* next;
    6. };
    7. typedef struct {
    8. int top;
    9. int total;
    10. struct LRUInfo * head;
    11. struct LRUInfo * rear;
    12. struct LRUInfo lruinfo[10001];
    13. } LRUCache;
    14. LRUCache* lRUCacheCreate(int capacity) {
    15. LRUCache* obj = calloc(1, sizeof(LRUCache));
    16. obj->total = capacity;
    17. obj->head = calloc(1, sizeof(struct LRUInfo));
    18. obj->rear = calloc(1, sizeof(struct LRUInfo));
    19. obj->head->next = obj->rear;
    20. obj->rear->pre = obj->head;
    21. return obj;
    22. }
    23. int lRUCacheGet(LRUCache* obj, int key) {
    24. if (obj->lruinfo[key].val == 1) {
    25. obj->lruinfo[key].pre->next = obj->lruinfo[key].next;
    26. obj->lruinfo[key].next->pre = obj->lruinfo[key].pre;
    27. obj->rear->pre->next = obj->lruinfo + key;
    28. obj->lruinfo[key].pre = obj->rear->pre;
    29. obj->lruinfo[key].next = obj->rear;
    30. obj->rear->pre = obj->lruinfo + key;
    31. return obj->lruinfo[key].value;
    32. }
    33. return -1;
    34. }
    35. void lRUCachePut(LRUCache* obj, int key, int value) {
    36. if (obj->lruinfo[key].val == 0 && obj->top < obj->total) {
    37. (obj->top)++;
    38. obj->rear->pre->next = obj->lruinfo + key;
    39. obj->lruinfo[key].pre = obj->rear->pre;
    40. obj->lruinfo[key].next = obj->rear;
    41. obj->lruinfo[key].val = 1;
    42. obj->lruinfo[key].value = value;
    43. obj->rear->pre = obj->lruinfo + key;
    44. } else if (obj->lruinfo[key].val == 1){
    45. obj->lruinfo[key].pre->next = obj->lruinfo[key].next;
    46. obj->lruinfo[key].next->pre = obj->lruinfo[key].pre;
    47. obj->rear->pre->next = obj->lruinfo + key;
    48. obj->lruinfo[key].pre = obj->rear->pre;
    49. obj->lruinfo[key].next = obj->rear;
    50. obj->lruinfo[key].value = value;
    51. obj->rear->pre = obj->lruinfo + key;
    52. } else if (obj->lruinfo[key].val == 0 && obj->top >= obj->total && obj->head->next != NULL) {
    53. obj->lruinfo[key].val = 1;
    54. obj->lruinfo[key].value = value;
    55. obj->rear->pre->next = obj->lruinfo + key;
    56. obj->lruinfo[key].pre = obj->rear->pre;
    57. obj->lruinfo[key].next = obj->rear;
    58. obj->rear->pre = obj->lruinfo + key;
    59. obj->head->next->val = 0;
    60. obj->head->next = obj->head->next->next;
    61. obj->head->next->pre = obj->head;
    62. }
    63. return;
    64. }
    65. void lRUCacheFree(LRUCache* obj) {
    66. free(obj);
    67. }
    68. /**
    69. * Your LRUCache struct will be instantiated and called as such:
    70. * LRUCache* obj = lRUCacheCreate(capacity);
    71. * int param_1 = lRUCacheGet(obj, key);
    72. * lRUCachePut(obj, key, value);
    73. * lRUCacheFree(obj);
    74. */

    分析:

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

    总结:

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

  • 相关阅读:
    RKE2 config containerd private registry (rke2配置私有仓库地址)
    云原生Kubernetes系列项目实战-k8s集群+高可用负载均衡层+防火墙
    32、多租户(multi-tenancy)
    文件共享服务器
    k8s教程(10)-pod生命周期、重启策略及健康检查
    Unity 关于低版本是否可以引用高版本构建内容的可行性验证
    社科院与杜兰大学能源管理硕士项目——用你的脚步,走出自己的风景
    HTML <tr> 标签
    单片机论文参考:1、基于单片机的电子琴
    CSRF跨站请求伪造漏洞分析
  • 原文地址:https://blog.csdn.net/si_mple_/article/details/133102974