zoukankan      html  css  js  c++  java
  • 力扣算法题—146LRU缓存机制

    【题目】

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

    获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
    写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

    进阶:

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

    示例:

    LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );

    cache.put(1, 1);
    cache.put(2, 2);
    cache.get(1); // 返回 1
    cache.put(3, 3); // 该操作会使得密钥 2 作废
    cache.get(2); // 返回 -1 (未找到)
    cache.put(4, 4); // 该操作会使得密钥 1 作废
    cache.get(1); // 返回 -1 (未找到)
    cache.get(3); // 返回 3
    cache.get(4); // 返回 4

    【解题思路】

    见博客:左神算法进阶班5_4设计可以变更的缓存结构(LRU)

    【代码】

     1 class LRUCache {
     2 public:
     3     LRUCache(int capacity) {
     4         this->capacity = capacity;
     5     }
     6 
     7     int get(int key) {
     8         if (map.find(key) == map.end())
     9             return -1;
    10         Node* p = map[key];
    11         update(p);//更新使用频率
    12         return p->val;
    13     }
    14 
    15     void put(int key, int value) {
    16         if (map.find(key) == map.end())//不存在就存入
    17         {
    18             if (this->map.size() == this->capacity)//缓存空间已满
    19             {
    20                 Node* p = this->head->next;
    21                 this->head->next = p->next;//删除位于链表头部的最不常用的节点
    22                 if (p->next == nullptr)//只有一个数据
    23                     end = head;
    24                 else
    25                     p->next->pre = head;
    26                 map.erase(p->key);//从表中删除,以留出空间                
    27                 delete p;
    28             }
    29             Node* p = new Node(key, value);//新插入的数据在链表尾
    30             this->end->next = p;
    31             p->pre = end;
    32             end = p;
    33             map[key] = p;//存入数据
    34         }
    35         else//存在,但要更新数的使用频率
    36         {
    37             Node* p = map[key];//得到在链表中的位置
    38             p->val = value;//更新数据值
    39             update(p);//更新使用频率
    40         }
    41     }
    42 
    43 private:
    44     struct Node
    45     {
    46         int key;
    47         int val;
    48         Node* pre;
    49         Node* next;
    50         Node(int k, int v) :key(k), val(v), pre(nullptr), next(nullptr) {}
    51     };
    52 
    53     int capacity = 0;
    54     hash_map<int, Node*>map;
    55     Node* head = new Node(' ', -1);//指向链表的头
    56     Node* end = head;//指向链表的尾
    57     void update(Node* p)
    58     {
    59         if (p == end)
    60             return;//p在链表尾部就不用移动了
    61         Node* q = p->pre;
    62         q->next = p->next;
    63         p->next->pre = q;
    64         end->next = p;
    65         p->pre = end;//更新p的使用率,并挪至链表尾部
    66         end = p;
    67     }
    68 };
    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  */
    76 
    77 void Test()
    78 {
    79     LRUCache* rr = new LRUCache(1);
    80     rr->put(2, 1);
    81     cout << rr->get(2) << endl;
    82     rr->put(2, 2);
    83     cout << rr->get(2) << endl;
    84     rr->get(2);
    85     rr->put(3, 2);
    86     rr->get(2);
    87     rr->get(3);
    88     
    89 
    90 }
  • 相关阅读:
    2020软件工程第一次个人编程作业
    2020软件工程第一次作业
    软件实践个人总结
    2020软件工程第四次编程作业-实验家族树
    2020软件工程个人编程作业
    软工实践个人总结
    2020软件工程结对编程之实验室程序实现
    2020软件工程第一次个人编程作业
    软工作业
    机器学习第四章笔记
  • 原文地址:https://www.cnblogs.com/zzw1024/p/11075357.html
Copyright © 2011-2022 走看看