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

  • 相关阅读:
    2022面试,Java面试项目推荐,15个项目吃透两个offer拿到手软
    区域气象-大气化学在线耦合模式(WRF/Chem)在大气环境领域实践技术应用
    【Jenkins】Jenkins构建前端流水线
    Rust 流程控制
    CSS性能优化
    正则表达式高阶(二)
    使用html+css+js实现一个静态页面(含源码)
    Java Web之Servlet技术
    Ubnutu上面配置Windows remote连接
    C语言三大结构
  • 原文地址:https://blog.csdn.net/si_mple_/article/details/133102974