牛客热题:设计LRU缓存结构

📟作者主页:慢热的陕西人

🌴专栏链接:力扣刷题日记

📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言

在这里插入图片描述

牛客热题:设计LRU缓存结构

题目链接

设计LRU缓存结构_牛客题霸_牛客网 (nowcoder.com)

方法一:map+双向链表

思路

set

​ step1:查看对应的key是否已经被set过

​ step2:如果set过就将对应的节点移动到链表头,并且在哈希中改变其val的值

​ step3:如果没有set过就构建一个新的节点在哈希中创建映射,然后将新的节点插入到链表的头部

​ step4:查看缓存空间是否溢出

​ step5: 如果溢出就删除对应的链表尾部的节点,然后将哈希中的映射删除掉,并释放掉对应的节点

get

​ step1:查看是否在哈希表中出现过

​ step2:如果出现过,将其在链表中的节点移动到链表头的位置,并返回对应的val

​ step3:如果没出现过,那么直接返回-1

代码

class Node
{
public:
    int _key;
    int _val;
    Node* _prev;
    Node* _next;
    //初始化
public:
    Node(int key, int val)
    {
        _key = key;
        _val = val;
        _prev = nullptr;
        _next = nullptr;
    }
};

class Solution {
public:
 Solution(int capacity)
 {
    size = capacity;
    head = new Node(0, 0);
    tail = new Node(0, 0);
    //将头节点和尾部节点连上
    head->_next = tail;
    tail->_prev = head;
 }
 
 int get(int key) 
 {
    if(hash.count(key))
    {
        MoveToHead(hash[key]);
        return hash[key]->_val;
    }
    else
    {
        return -1;
    } 
 }
 
 void set(int key, int value)
 {
    //1.是否已经被set过
    if(hash.count(key))
    {
        //2.将其节点移动到链表头
        MoveToHead(hash[key]);
        hash[key]->_val = value;
        cout << 2 << endl;
    }
    else 
    {
        //3.将新节点插入到链表的头部
        Node* NewNode = new Node(key, value);
        InsertToHead(NewNode);
        hash[key] = NewNode;

        //4.如果空间不够
        if(size <= 0)
        {
            //将链表尾部的节点去掉
            EraseLast();
            size++;
        }
        //5.减小空间
        size--;
    }
 }

void EraseLast()
{
    //先在哈希表中删除映射
    hash.erase(tail->_prev->_key);
    //在链表中删除
    Node* cur = tail->_prev;
    tail->_prev->_prev->_next = tail;
    tail->_prev = tail->_prev->_prev;
    delete cur;
    cur = nullptr;
}

void MoveToHead(Node* node)
{
    //已经是头部
    if(head == node->_prev)
    {
        return ;
    }
    //先将这个节点拆下来
    node->_prev->_next = node->_next;
    node->_next->_prev = node->_prev;
    
    InsertToHead(node);
}

void InsertToHead(Node* node)
{
    node->_next = head->_next;
    node->_prev = head;
    head->_next->_prev = node;
    head->_next = node;
}

private:
    int size;
    Node* head;
    Node* tail;
    map<int, Node*> hash;
};

复杂度

时间复杂度:O(1),不论是set操作还是get操作均在O(1)的时间复杂度

空间复杂度:O(N), 利用到了长度等于size+2的链表长度和对应的map

相关推荐

  1. 【LeetCode】100:LRU缓存

    2024-06-12 07:20:05       12 阅读
  2. leetcodeHOT146. LRU 缓存

    2024-06-12 07:20:05       17 阅读
  3. LeetCode-100:146. LRU 缓存

    2024-06-12 07:20:05       18 阅读
  4. 【LeetCode100】【链表】LRU缓存

    2024-06-12 07:20:05       23 阅读
  5. 【数据结构LRU缓存

    2024-06-12 07:20:05       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-12 07:20:05       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-12 07:20:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-12 07:20:05       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-12 07:20:05       20 阅读

热门阅读

  1. Oracle基本数据类型

    2024-06-12 07:20:05       8 阅读
  2. Oracle系统视图归纳总结及常用对象查询语句

    2024-06-12 07:20:05       7 阅读
  3. GIS之arcgis系列08:arcpy实现批量excel转矢量点

    2024-06-12 07:20:05       9 阅读
  4. uniapp使用webview内嵌H5的注意事项

    2024-06-12 07:20:05       5 阅读
  5. MFC四种方法编写多线程

    2024-06-12 07:20:05       5 阅读
  6. 使用net.sf.mpxj读取project的.mpp文件

    2024-06-12 07:20:05       10 阅读