• 设计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) 的平均时间复杂度运行。

    示例:

    输入
    ["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
    [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
    输出
    [null, null, null, 1, null, -1, null, -1, 3, 4]

    解释
    LRUCache lRUCache = new LRUCache(2);
    lRUCache.put(1, 1); // 缓存是 {1=1}
    lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
    lRUCache.get(1);    // 返回 1
    lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
    lRUCache.get(2);    // 返回 -1 (未找到)
    lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
    lRUCache.get(1);    // 返回 -1 (未找到)
    lRUCache.get(3);    // 返回 3
    lRUCache.get(4);    // 返回 4
     

    提示:

    1 <= capacity <= 3000
    0 <= key <= 10000
    0 <= value <= 105
    最多调用 2 * 105 次 get 和 put

    1. struct DoubleLinkNode{
    2. int key;
    3. int value;
    4. DoubleLinkNode* next;
    5. DoubleLinkNode* prev;
    6. DoubleLinkNode():key(0),value(0),next(nullptr),prev(nullptr){}
    7. DoubleLinkNode(int k,int v):key(k),value(v),next(nullptr),prev(nullptr){}
    8. };
    9. class LRUCache {
    10. public:
    11. LRUCache(int capacity):size(0),capacity(capacity) {
    12. dummy_head=new DoubleLinkNode();
    13. dummy_tail=new DoubleLinkNode();
    14. dummy_head->next=dummy_tail;
    15. dummy_tail->prev=dummy_head;
    16. }
    17. int get(int key) {
    18. if(!cache.count(key)){
    19. return -1;
    20. }else{
    21. DoubleLinkNode* node=cache[key];
    22. moveToHead(node);
    23. return node->value;
    24. }
    25. }
    26. void put(int key, int value) {
    27. if(cache.count(key)){
    28. DoubleLinkNode* node=cache[key];
    29. node->value=value;
    30. moveToHead(node);
    31. }else{
    32. DoubleLinkNode* node=new DoubleLinkNode(key,value);
    33. cache[key]=node;
    34. addToHead(node);
    35. size++;
    36. if(size>capacity){
    37. DoubleLinkNode* del=deleteTail();
    38. cache.erase(del->key);
    39. --size;
    40. delete del;
    41. }
    42. }
    43. }
    44. void addToHead(DoubleLinkNode* node){
    45. node->next=dummy_head->next;
    46. node->prev=dummy_head;
    47. dummy_head->next->prev=node;
    48. dummy_head->next=node;
    49. }
    50. void removeNode(DoubleLinkNode* node){
    51. node->next->prev=node->prev;
    52. node->prev->next=node->next;
    53. }
    54. void moveToHead(DoubleLinkNode* node){
    55. removeNode(node);
    56. addToHead(node);
    57. }
    58. DoubleLinkNode* deleteTail(){
    59. DoubleLinkNode* node=dummy_tail->prev;
    60. removeNode(node);
    61. return node;
    62. }
    63. private:
    64. unordered_map<int,DoubleLinkNode*>cache;
    65. int size;
    66. int capacity;
    67. DoubleLinkNode* dummy_head;
    68. DoubleLinkNode* dummy_tail;
    69. };
    70. /**
    71. * Your LRUCache object will be instantiated and called as such:
    72. * LRUCache* obj = new LRUCache(capacity);
    73. * int param_1 = obj->get(key);
    74. * obj->put(key,value);
    75. */

  • 相关阅读:
    一维卷积英语电影评论情感分类项目
    Redis 内存优化神技,小内存保存大数据
    uniapp项目打包H5后 希望可以修改固定的配置(接口地址,系统名称等)
    Vue3 瀑布流 动态加载图片,下拉无限滚动
    理解Java程序的执行
    Timed out waiting for process (xxx) to appear on错误
    v-model的各种使用状态和使用结果
    Squeeze-and-Excitation Networks总结
    采用对象映射的方式在前端进行数据字典赋值
    JavaScript中this关键字实践
  • 原文地址:https://blog.csdn.net/Jason6620/article/details/126444998