• LeetCode146 LRU缓存机制


    运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。

    获取数据 get(key) - 如果关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。
    写入数据 put(key, value) - 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字/值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

    进阶:

    你是否可以在 O(1) 时间复杂度内完成这两种操作?

    使用一个哈希表记录key,用双链表记录key,value和顺序。哈希表中key对应的是双链表节点的指针。每次查询就把当前节点移动到链表的头部。每次put的时候也会把put的节点移动到头部,同时判断是否超出capacity,如果超出就删除dummyhead前面的一个节点。

    注意delete释放空间,修改指针要修改全。

    链表双向主要是可以在O(1)时间内找到需要删除的节点(即dummyTail前一个节点)。节点需要记录key主要是删除的时候得到key,这样才能在O(1)时间内在哈希表中找到并删除。

     1 struct DLinkedNode {
     2     int key, value;
     3     DLinkedNode* prev;
     4     DLinkedNode* next;
     5     DLinkedNode() : key(0), value(0), prev(nullptr), next(nullptr) {}
     6     DLinkedNode(int _key, int _value) : key(_key), value(_value), prev(nullptr), next(nullptr) {}
     7 };
     8 
     9 struct LRU_Node {
    10     int key;
    11     int value;
    12     LRU_Node* next;
    13     LRU_Node* prev;
    14     LRU_Node() : key(0), value(0), next(nullptr), prev(nullptr) {}
    15     LRU_Node(int _key, int _value) :key(_key), value(_value), next(nullptr), prev(nullptr) {}
    16 };
    17 
    18 class LRUCache {
    19 private:
    20     int num;
    21     int capacity;
    22     unordered_map<int, LRU_Node*> map_LRU;
    23     LRU_Node* dummyHead;
    24     LRU_Node* dummyTail;
    25 
    26 public:
    27     LRUCache(int _capacity) {
    28         num = 0;
    29         capacity = _capacity;
    30         dummyHead = new LRU_Node(-1, -1);
    31         dummyTail = new LRU_Node(-1, -1);
    32         dummyHead->next = dummyTail;
    33         dummyTail->prev = dummyHead;
    34         map_LRU.clear();
    35         cout << "LRUCache is created.
    ";
    36     }
    37 
    38     LRU_Node* moveToHead(LRU_Node* cur) {
    39         cur->prev->next = cur->next;
    40         cur->next->prev = cur->prev;
    41         cur->next = dummyHead->next;
    42         cur->prev = dummyHead;
    43         dummyHead->next = cur;
    44         cur->next->prev = cur;
    45         return cur;
    46     }
    47 
    48     LRU_Node* insertHead(LRU_Node* new_node) {
    49         new_node->next = dummyHead->next;
    50         new_node->prev = dummyHead;
    51         dummyHead->next = new_node;
    52         new_node->next->prev = new_node;
    53         return new_node;
    54     }
    55 
    56     int get(int key) {
    57         if (map_LRU.find(key) != map_LRU.end()) {
    58             LRU_Node* cur = map_LRU[key];
    59             cur = moveToHead(cur);
    60             map_LRU[key] = cur;
    61             return cur->value;
    62         }
    63         return -1;
    64     }
    65 
    66     void put(int key, int value) {
    67         if (map_LRU.find(key) != map_LRU.end()) {
    68             LRU_Node* cur = map_LRU[key];
    69             cur->value = value;
    70             cur = moveToHead(cur);
    71             map_LRU[key] = cur;
    72         }
    73         else {
    74             LRU_Node* new_node = new LRU_Node(key, value);
    75             new_node = insertHead(new_node);
    76             map_LRU[key] = new_node;
    77             if (num != capacity)
    78                 ++num;
    79             else {
    80                 int deleteKey = dummyTail->prev->key;
    81                 LRU_Node* toBeDelete=dummyTail->prev;
    82                 dummyTail->prev=dummyTail->prev->prev;
    83                 dummyTail->prev->next=dummyTail;
    84                 delete toBeDelete;
    85                 toBeDelete=nullptr;
    86                 auto it = map_LRU.find(deleteKey);
    87                 map_LRU.erase(it);
    88             }
    89         }
    90         return;
    91     }
    92 };
    93 
    94 /**
    95  * Your LRUCache object will be instantiated and called as such:
    96  * LRUCache* obj = new LRUCache(capacity);
    97  * int param_1 = obj->get(key);
    98  * obj->put(key,value);
    99  */
  • 相关阅读:
    函数传参总结
    集合操作总结
    深浅拷贝总结
    三级列表展示
    文件操作总结
    vue-router之嵌套路由
    vue-router之动态路由
    Sublime编辑VUE实现代码高亮
    Windows系统下Vue开发环境搭建详解版
    C#调用快递鸟电子面单API实现批量打印电子面单功能
  • 原文地址:https://www.cnblogs.com/rookiez/p/13302297.html
Copyright © 2020-2023  润新知